andro1241 commited on
Commit
edcba35
·
verified ·
1 Parent(s): f2d3a9c

Upload 44 files

Browse files
Files changed (43) hide show
  1. uis/components/about.py +41 -0
  2. uis/components/age_modifier_options.py +64 -0
  3. uis/components/background_remover_options.py +165 -0
  4. uis/components/benchmark.py +51 -0
  5. uis/components/benchmark_options.py +54 -0
  6. uis/components/deep_swapper_options.py +64 -0
  7. uis/components/download.py +48 -0
  8. uis/components/execution.py +48 -0
  9. uis/components/execution_thread_count.py +29 -0
  10. uis/components/expression_restorer_options.py +80 -0
  11. uis/components/face_debugger_options.py +40 -0
  12. uis/components/face_detector.py +103 -0
  13. uis/components/face_editor_options.py +272 -0
  14. uis/components/face_enhancer_options.py +81 -0
  15. uis/components/face_landmarker.py +50 -0
  16. uis/components/face_masker.py +181 -0
  17. uis/components/face_selector.py +236 -0
  18. uis/components/face_swapper_options.py +84 -0
  19. uis/components/face_tracker.py +32 -0
  20. uis/components/frame_colorizer_options.py +81 -0
  21. uis/components/frame_enhancer_options.py +64 -0
  22. uis/components/instant_runner.py +110 -0
  23. uis/components/job_list.py +50 -0
  24. uis/components/job_list_options.py +35 -0
  25. uis/components/job_manager.py +194 -0
  26. uis/components/job_runner.py +142 -0
  27. uis/components/lip_syncer_options.py +64 -0
  28. uis/components/memory.py +27 -0
  29. uis/components/output.py +48 -0
  30. uis/components/output_options.py +184 -0
  31. uis/components/preview.py +306 -0
  32. uis/components/preview_options.py +62 -0
  33. uis/components/processors.py +49 -0
  34. uis/components/source.py +61 -0
  35. uis/components/target.py +65 -0
  36. uis/components/temp_frame.py +42 -0
  37. uis/components/terminal.py +80 -0
  38. uis/components/trim_frame.py +62 -0
  39. uis/components/ui_workflow.py +21 -0
  40. uis/components/voice_extractor.py +56 -0
  41. uis/components/webcam.py +116 -0
  42. uis/components/webcam_options.py +49 -0
  43. uis/components/workflow.py +27 -0
uis/components/about.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ from typing import Optional
3
+
4
+ import gradio
5
+
6
+ from facefusion import metadata, translator
7
+
8
+ METADATA_BUTTON : Optional[gradio.Button] = None
9
+ ACTION_BUTTON : Optional[gradio.Button] = None
10
+
11
+
12
+ def render() -> None:
13
+ global METADATA_BUTTON
14
+ global ACTION_BUTTON
15
+
16
+ action = random.choice(
17
+ [
18
+ {
19
+ 'translator': translator.get('about.fund'),
20
+ 'url': 'https://fund.facefusion.io'
21
+ },
22
+ {
23
+ 'translator': translator.get('about.subscribe'),
24
+ 'url': 'https://subscribe.facefusion.io'
25
+ },
26
+ {
27
+ 'translator': translator.get('about.join'),
28
+ 'url': 'https://join.facefusion.io'
29
+ }
30
+ ])
31
+
32
+ METADATA_BUTTON = gradio.Button(
33
+ value = metadata.get('name') + ' ' + metadata.get('version'),
34
+ variant = 'primary',
35
+ link = metadata.get('url')
36
+ )
37
+ ACTION_BUTTON = gradio.Button(
38
+ value = action.get('translator'),
39
+ link = action.get('url'),
40
+ size = 'sm'
41
+ )
uis/components/age_modifier_options.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.common_helper import calculate_float_step
7
+ from facefusion.processors.core import load_processor_module
8
+ from facefusion.processors.modules.age_modifier import choices as age_modifier_choices
9
+ from facefusion.processors.modules.age_modifier.types import AgeModifierModel
10
+ from facefusion.uis.core import get_ui_component, register_ui_component
11
+
12
+ AGE_MODIFIER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
13
+ AGE_MODIFIER_DIRECTION_SLIDER : Optional[gradio.Slider] = None
14
+
15
+
16
+ def render() -> None:
17
+ global AGE_MODIFIER_MODEL_DROPDOWN
18
+ global AGE_MODIFIER_DIRECTION_SLIDER
19
+
20
+ has_age_modifier = 'age_modifier' in state_manager.get_item('processors')
21
+ AGE_MODIFIER_MODEL_DROPDOWN = gradio.Dropdown(
22
+ label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.age_modifier'),
23
+ choices = age_modifier_choices.age_modifier_models,
24
+ value = state_manager.get_item('age_modifier_model'),
25
+ visible = has_age_modifier
26
+ )
27
+ AGE_MODIFIER_DIRECTION_SLIDER = gradio.Slider(
28
+ label = translator.get('uis.direction_slider', 'facefusion.processors.modules.age_modifier'),
29
+ value = state_manager.get_item('age_modifier_direction'),
30
+ step = calculate_float_step(age_modifier_choices.age_modifier_direction_range),
31
+ minimum = age_modifier_choices.age_modifier_direction_range[0],
32
+ maximum = age_modifier_choices.age_modifier_direction_range[-1],
33
+ visible = has_age_modifier
34
+ )
35
+ register_ui_component('age_modifier_model_dropdown', AGE_MODIFIER_MODEL_DROPDOWN)
36
+ register_ui_component('age_modifier_direction_slider', AGE_MODIFIER_DIRECTION_SLIDER)
37
+
38
+
39
+ def listen() -> None:
40
+ AGE_MODIFIER_MODEL_DROPDOWN.change(update_age_modifier_model, inputs = AGE_MODIFIER_MODEL_DROPDOWN, outputs = AGE_MODIFIER_MODEL_DROPDOWN)
41
+ AGE_MODIFIER_DIRECTION_SLIDER.release(update_age_modifier_direction, inputs = AGE_MODIFIER_DIRECTION_SLIDER)
42
+
43
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
44
+ if processors_checkbox_group:
45
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ AGE_MODIFIER_MODEL_DROPDOWN, AGE_MODIFIER_DIRECTION_SLIDER ])
46
+
47
+
48
+ def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider]:
49
+ has_age_modifier = 'age_modifier' in processors
50
+ return gradio.Dropdown(visible = has_age_modifier), gradio.Slider(visible = has_age_modifier)
51
+
52
+
53
+ def update_age_modifier_model(age_modifier_model : AgeModifierModel) -> gradio.Dropdown:
54
+ age_modifier_module = load_processor_module('age_modifier')
55
+ age_modifier_module.clear_inference_pool()
56
+ state_manager.set_item('age_modifier_model', age_modifier_model)
57
+
58
+ if age_modifier_module.pre_check():
59
+ return gradio.Dropdown(value = state_manager.get_item('age_modifier_model'))
60
+ return gradio.Dropdown()
61
+
62
+
63
+ def update_age_modifier_direction(age_modifier_direction : float) -> None:
64
+ state_manager.set_item('age_modifier_direction', int(age_modifier_direction))
uis/components/background_remover_options.py ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.common_helper import calculate_int_step
7
+ from facefusion.processors.core import load_processor_module
8
+ from facefusion.processors.modules.background_remover import choices as background_remover_choices
9
+ from facefusion.processors.modules.background_remover.types import BackgroundRemoverModel
10
+ from facefusion.sanitizer import sanitize_int_range
11
+ from facefusion.uis.core import get_ui_component, register_ui_component
12
+
13
+ BACKGROUND_REMOVER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
14
+ BACKGROUND_REMOVER_FILL_COLOR_WRAPPER : Optional[gradio.Group] = None
15
+ BACKGROUND_REMOVER_FILL_COLOR_RED_NUMBER : Optional[gradio.Number] = None
16
+ BACKGROUND_REMOVER_FILL_COLOR_GREEN_NUMBER : Optional[gradio.Number] = None
17
+ BACKGROUND_REMOVER_FILL_COLOR_BLUE_NUMBER : Optional[gradio.Number] = None
18
+ BACKGROUND_REMOVER_FILL_COLOR_ALPHA_NUMBER : Optional[gradio.Number] = None
19
+ BACKGROUND_REMOVER_DESPILL_COLOR_WRAPPER : Optional[gradio.Group] = None
20
+ BACKGROUND_REMOVER_DESPILL_COLOR_RED_NUMBER : Optional[gradio.Number] = None
21
+ BACKGROUND_REMOVER_DESPILL_COLOR_GREEN_NUMBER : Optional[gradio.Number] = None
22
+ BACKGROUND_REMOVER_DESPILL_COLOR_BLUE_NUMBER : Optional[gradio.Number] = None
23
+ BACKGROUND_REMOVER_DESPILL_COLOR_ALPHA_NUMBER : Optional[gradio.Number] = None
24
+
25
+
26
+ def render() -> None:
27
+ global BACKGROUND_REMOVER_MODEL_DROPDOWN
28
+ global BACKGROUND_REMOVER_FILL_COLOR_WRAPPER
29
+ global BACKGROUND_REMOVER_FILL_COLOR_RED_NUMBER
30
+ global BACKGROUND_REMOVER_FILL_COLOR_GREEN_NUMBER
31
+ global BACKGROUND_REMOVER_FILL_COLOR_BLUE_NUMBER
32
+ global BACKGROUND_REMOVER_FILL_COLOR_ALPHA_NUMBER
33
+ global BACKGROUND_REMOVER_DESPILL_COLOR_WRAPPER
34
+ global BACKGROUND_REMOVER_DESPILL_COLOR_RED_NUMBER
35
+ global BACKGROUND_REMOVER_DESPILL_COLOR_GREEN_NUMBER
36
+ global BACKGROUND_REMOVER_DESPILL_COLOR_BLUE_NUMBER
37
+ global BACKGROUND_REMOVER_DESPILL_COLOR_ALPHA_NUMBER
38
+
39
+ has_background_remover = 'background_remover' in state_manager.get_item('processors')
40
+ background_remover_fill_color = state_manager.get_item('background_remover_fill_color')
41
+ background_remover_despill_color = state_manager.get_item('background_remover_despill_color')
42
+ BACKGROUND_REMOVER_MODEL_DROPDOWN = gradio.Dropdown(
43
+ label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.background_remover'),
44
+ choices = background_remover_choices.background_remover_models,
45
+ value = state_manager.get_item('background_remover_model'),
46
+ visible = has_background_remover
47
+ )
48
+ with gradio.Group(visible = has_background_remover) as BACKGROUND_REMOVER_FILL_COLOR_WRAPPER:
49
+ with gradio.Row():
50
+ BACKGROUND_REMOVER_FILL_COLOR_RED_NUMBER = gradio.Number(
51
+ label = translator.get('uis.fill_color_red_number', 'facefusion.processors.modules.background_remover'),
52
+ value = background_remover_fill_color[0],
53
+ minimum = background_remover_choices.background_remover_color_range[0],
54
+ maximum = background_remover_choices.background_remover_color_range[-1],
55
+ step = calculate_int_step(background_remover_choices.background_remover_color_range)
56
+ )
57
+ BACKGROUND_REMOVER_FILL_COLOR_GREEN_NUMBER = gradio.Number(
58
+ label = translator.get('uis.fill_color_green_number', 'facefusion.processors.modules.background_remover'),
59
+ value = background_remover_fill_color[1],
60
+ minimum = background_remover_choices.background_remover_color_range[0],
61
+ maximum = background_remover_choices.background_remover_color_range[-1],
62
+ step = calculate_int_step(background_remover_choices.background_remover_color_range)
63
+ )
64
+ with gradio.Row():
65
+ BACKGROUND_REMOVER_FILL_COLOR_BLUE_NUMBER = gradio.Number(
66
+ label = translator.get('uis.fill_color_blue_number', 'facefusion.processors.modules.background_remover'),
67
+ value = background_remover_fill_color[2],
68
+ minimum = background_remover_choices.background_remover_color_range[0],
69
+ maximum = background_remover_choices.background_remover_color_range[-1],
70
+ step = calculate_int_step(background_remover_choices.background_remover_color_range)
71
+ )
72
+ BACKGROUND_REMOVER_FILL_COLOR_ALPHA_NUMBER = gradio.Number(
73
+ label = translator.get('uis.fill_color_alpha_number', 'facefusion.processors.modules.background_remover'),
74
+ value = background_remover_fill_color[3],
75
+ minimum = background_remover_choices.background_remover_color_range[0],
76
+ maximum = background_remover_choices.background_remover_color_range[-1],
77
+ step = calculate_int_step(background_remover_choices.background_remover_color_range)
78
+ )
79
+ with gradio.Group(visible = has_background_remover) as BACKGROUND_REMOVER_DESPILL_COLOR_WRAPPER:
80
+ with gradio.Row():
81
+ BACKGROUND_REMOVER_DESPILL_COLOR_RED_NUMBER = gradio.Number(
82
+ label = translator.get('uis.despill_color_red_number', 'facefusion.processors.modules.background_remover'),
83
+ value = background_remover_despill_color[0],
84
+ minimum = background_remover_choices.background_remover_color_range[0],
85
+ maximum = background_remover_choices.background_remover_color_range[-1],
86
+ step = calculate_int_step(background_remover_choices.background_remover_color_range)
87
+ )
88
+ BACKGROUND_REMOVER_DESPILL_COLOR_GREEN_NUMBER = gradio.Number(
89
+ label = translator.get('uis.despill_color_green_number', 'facefusion.processors.modules.background_remover'),
90
+ value = background_remover_despill_color[1],
91
+ minimum = background_remover_choices.background_remover_color_range[0],
92
+ maximum = background_remover_choices.background_remover_color_range[-1],
93
+ step = calculate_int_step(background_remover_choices.background_remover_color_range)
94
+ )
95
+ with gradio.Row():
96
+ BACKGROUND_REMOVER_DESPILL_COLOR_BLUE_NUMBER = gradio.Number(
97
+ label = translator.get('uis.despill_color_blue_number', 'facefusion.processors.modules.background_remover'),
98
+ value = background_remover_despill_color[2],
99
+ minimum = background_remover_choices.background_remover_color_range[0],
100
+ maximum = background_remover_choices.background_remover_color_range[-1],
101
+ step = calculate_int_step(background_remover_choices.background_remover_color_range)
102
+ )
103
+ BACKGROUND_REMOVER_DESPILL_COLOR_ALPHA_NUMBER = gradio.Number(
104
+ label = translator.get('uis.despill_color_alpha_number', 'facefusion.processors.modules.background_remover'),
105
+ value = background_remover_despill_color[3],
106
+ minimum = background_remover_choices.background_remover_color_range[0],
107
+ maximum = background_remover_choices.background_remover_color_range[-1],
108
+ step = calculate_int_step(background_remover_choices.background_remover_color_range)
109
+ )
110
+ register_ui_component('background_remover_model_dropdown', BACKGROUND_REMOVER_MODEL_DROPDOWN)
111
+ register_ui_component('background_remover_fill_color_red_number', BACKGROUND_REMOVER_FILL_COLOR_RED_NUMBER)
112
+ register_ui_component('background_remover_fill_color_green_number', BACKGROUND_REMOVER_FILL_COLOR_GREEN_NUMBER)
113
+ register_ui_component('background_remover_fill_color_blue_number', BACKGROUND_REMOVER_FILL_COLOR_BLUE_NUMBER)
114
+ register_ui_component('background_remover_fill_color_alpha_number', BACKGROUND_REMOVER_FILL_COLOR_ALPHA_NUMBER)
115
+ register_ui_component('background_remover_despill_color_red_number', BACKGROUND_REMOVER_DESPILL_COLOR_RED_NUMBER)
116
+ register_ui_component('background_remover_despill_color_green_number', BACKGROUND_REMOVER_DESPILL_COLOR_GREEN_NUMBER)
117
+ register_ui_component('background_remover_despill_color_blue_number', BACKGROUND_REMOVER_DESPILL_COLOR_BLUE_NUMBER)
118
+ register_ui_component('background_remover_despill_color_alpha_number', BACKGROUND_REMOVER_DESPILL_COLOR_ALPHA_NUMBER)
119
+
120
+
121
+ def listen() -> None:
122
+ BACKGROUND_REMOVER_MODEL_DROPDOWN.change(update_background_remover_model, inputs = BACKGROUND_REMOVER_MODEL_DROPDOWN, outputs = BACKGROUND_REMOVER_MODEL_DROPDOWN)
123
+ background_remover_fill_color_inputs = [ BACKGROUND_REMOVER_FILL_COLOR_RED_NUMBER, BACKGROUND_REMOVER_FILL_COLOR_GREEN_NUMBER, BACKGROUND_REMOVER_FILL_COLOR_BLUE_NUMBER, BACKGROUND_REMOVER_FILL_COLOR_ALPHA_NUMBER ]
124
+ background_remover_despill_color_inputs = [ BACKGROUND_REMOVER_DESPILL_COLOR_RED_NUMBER, BACKGROUND_REMOVER_DESPILL_COLOR_GREEN_NUMBER, BACKGROUND_REMOVER_DESPILL_COLOR_BLUE_NUMBER, BACKGROUND_REMOVER_DESPILL_COLOR_ALPHA_NUMBER ]
125
+
126
+ for background_remover_fill_color_input in background_remover_fill_color_inputs:
127
+ background_remover_fill_color_input.change(update_background_remover_fill_color, inputs = background_remover_fill_color_inputs)
128
+
129
+ for background_remover_despill_color_input in background_remover_despill_color_inputs:
130
+ background_remover_despill_color_input.change(update_background_remover_despill_color, inputs = background_remover_despill_color_inputs)
131
+
132
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
133
+ if processors_checkbox_group:
134
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ BACKGROUND_REMOVER_MODEL_DROPDOWN, BACKGROUND_REMOVER_FILL_COLOR_WRAPPER, BACKGROUND_REMOVER_DESPILL_COLOR_WRAPPER ])
135
+
136
+
137
+ def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Group, gradio.Group]:
138
+ has_background_remover = 'background_remover' in processors
139
+ return gradio.Dropdown(visible = has_background_remover), gradio.Group(visible = has_background_remover), gradio.Group(visible = has_background_remover)
140
+
141
+
142
+ def update_background_remover_model(background_remover_model : BackgroundRemoverModel) -> gradio.Dropdown:
143
+ background_remover_module = load_processor_module('background_remover')
144
+ background_remover_module.clear_inference_pool()
145
+ state_manager.set_item('background_remover_model', background_remover_model)
146
+
147
+ if background_remover_module.pre_check():
148
+ return gradio.Dropdown(value = state_manager.get_item('background_remover_model'))
149
+ return gradio.Dropdown()
150
+
151
+
152
+ def update_background_remover_fill_color(red : int, green : int, blue : int, alpha : int) -> None:
153
+ red = sanitize_int_range(red, background_remover_choices.background_remover_color_range)
154
+ green = sanitize_int_range(green, background_remover_choices.background_remover_color_range)
155
+ blue = sanitize_int_range(blue, background_remover_choices.background_remover_color_range)
156
+ alpha = sanitize_int_range(alpha, background_remover_choices.background_remover_color_range)
157
+ state_manager.set_item('background_remover_fill_color', (red, green, blue, alpha))
158
+
159
+
160
+ def update_background_remover_despill_color(red : int, green : int, blue : int, alpha : int) -> None:
161
+ red = sanitize_int_range(red, background_remover_choices.background_remover_color_range)
162
+ green = sanitize_int_range(green, background_remover_choices.background_remover_color_range)
163
+ blue = sanitize_int_range(blue, background_remover_choices.background_remover_color_range)
164
+ alpha = sanitize_int_range(alpha, background_remover_choices.background_remover_color_range)
165
+ state_manager.set_item('background_remover_despill_color', (red, green, blue, alpha))
uis/components/benchmark.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Iterator, List, Optional
2
+
3
+ import gradio
4
+
5
+ from facefusion import benchmarker, state_manager, translator
6
+
7
+ BENCHMARK_BENCHMARKS_DATAFRAME : Optional[gradio.Dataframe] = None
8
+ BENCHMARK_START_BUTTON : Optional[gradio.Button] = None
9
+
10
+
11
+ def render() -> None:
12
+ global BENCHMARK_BENCHMARKS_DATAFRAME
13
+ global BENCHMARK_START_BUTTON
14
+
15
+ BENCHMARK_BENCHMARKS_DATAFRAME = gradio.Dataframe(
16
+ headers =
17
+ [
18
+ 'target_path',
19
+ 'cycle_count',
20
+ 'average_run',
21
+ 'fastest_run',
22
+ 'slowest_run',
23
+ 'relative_fps'
24
+ ],
25
+ datatype =
26
+ [
27
+ 'str',
28
+ 'number',
29
+ 'number',
30
+ 'number',
31
+ 'number',
32
+ 'number'
33
+ ],
34
+ show_label = False
35
+ )
36
+ BENCHMARK_START_BUTTON = gradio.Button(
37
+ value = translator.get('uis.start_button'),
38
+ variant = 'primary',
39
+ size = 'sm'
40
+ )
41
+
42
+
43
+ def listen() -> None:
44
+ BENCHMARK_START_BUTTON.click(start, outputs = BENCHMARK_BENCHMARKS_DATAFRAME)
45
+
46
+
47
+ def start() -> Iterator[List[Any]]:
48
+ state_manager.sync_state()
49
+
50
+ for benchmark in benchmarker.run():
51
+ yield [ list(benchmark_set.values()) for benchmark_set in benchmark ]
uis/components/benchmark_options.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import state_manager, translator
7
+ from facefusion.common_helper import calculate_int_step
8
+ from facefusion.types import BenchmarkMode, BenchmarkResolution
9
+
10
+ BENCHMARK_MODE_DROPDOWN : Optional[gradio.Dropdown] = None
11
+ BENCHMARK_RESOLUTIONS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
12
+ BENCHMARK_CYCLE_COUNT_SLIDER : Optional[gradio.Button] = None
13
+
14
+
15
+ def render() -> None:
16
+ global BENCHMARK_MODE_DROPDOWN
17
+ global BENCHMARK_RESOLUTIONS_CHECKBOX_GROUP
18
+ global BENCHMARK_CYCLE_COUNT_SLIDER
19
+
20
+ BENCHMARK_MODE_DROPDOWN = gradio.Dropdown(
21
+ label = translator.get('uis.benchmark_mode_dropdown'),
22
+ choices = facefusion.choices.benchmark_modes,
23
+ value = state_manager.get_item('benchmark_mode')
24
+ )
25
+ BENCHMARK_RESOLUTIONS_CHECKBOX_GROUP = gradio.CheckboxGroup(
26
+ label = translator.get('uis.benchmark_resolutions_checkbox_group'),
27
+ choices = facefusion.choices.benchmark_resolutions,
28
+ value = state_manager.get_item('benchmark_resolutions')
29
+ )
30
+ BENCHMARK_CYCLE_COUNT_SLIDER = gradio.Slider(
31
+ label = translator.get('uis.benchmark_cycle_count_slider'),
32
+ value = state_manager.get_item('benchmark_cycle_count'),
33
+ step = calculate_int_step(facefusion.choices.benchmark_cycle_count_range),
34
+ minimum = facefusion.choices.benchmark_cycle_count_range[0],
35
+ maximum = facefusion.choices.benchmark_cycle_count_range[-1]
36
+ )
37
+
38
+
39
+ def listen() -> None:
40
+ BENCHMARK_MODE_DROPDOWN.change(update_benchmark_mode, inputs = BENCHMARK_MODE_DROPDOWN)
41
+ BENCHMARK_RESOLUTIONS_CHECKBOX_GROUP.change(update_benchmark_resolutions, inputs = BENCHMARK_RESOLUTIONS_CHECKBOX_GROUP)
42
+ BENCHMARK_CYCLE_COUNT_SLIDER.release(update_benchmark_cycle_count, inputs = BENCHMARK_CYCLE_COUNT_SLIDER)
43
+
44
+
45
+ def update_benchmark_mode(benchmark_mode : BenchmarkMode) -> None:
46
+ state_manager.set_item('benchmark_mode', benchmark_mode)
47
+
48
+
49
+ def update_benchmark_resolutions(benchmark_resolutions : List[BenchmarkResolution]) -> None:
50
+ state_manager.set_item('benchmark_resolutions', benchmark_resolutions)
51
+
52
+
53
+ def update_benchmark_cycle_count(benchmark_cycle_count : int) -> None:
54
+ state_manager.set_item('benchmark_cycle_count', benchmark_cycle_count)
uis/components/deep_swapper_options.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.common_helper import calculate_int_step
7
+ from facefusion.processors.core import load_processor_module
8
+ from facefusion.processors.modules.deep_swapper import choices as deep_swapper_choices
9
+ from facefusion.processors.modules.deep_swapper.types import DeepSwapperModel
10
+ from facefusion.uis.core import get_ui_component, register_ui_component
11
+
12
+ DEEP_SWAPPER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
13
+ DEEP_SWAPPER_MORPH_SLIDER : Optional[gradio.Slider] = None
14
+
15
+
16
+ def render() -> None:
17
+ global DEEP_SWAPPER_MODEL_DROPDOWN
18
+ global DEEP_SWAPPER_MORPH_SLIDER
19
+
20
+ has_deep_swapper = 'deep_swapper' in state_manager.get_item('processors')
21
+ DEEP_SWAPPER_MODEL_DROPDOWN = gradio.Dropdown(
22
+ label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.deep_swapper'),
23
+ choices = deep_swapper_choices.deep_swapper_models,
24
+ value = state_manager.get_item('deep_swapper_model'),
25
+ visible = has_deep_swapper
26
+ )
27
+ DEEP_SWAPPER_MORPH_SLIDER = gradio.Slider(
28
+ label = translator.get('uis.morph_slider', 'facefusion.processors.modules.deep_swapper'),
29
+ value = state_manager.get_item('deep_swapper_morph'),
30
+ step = calculate_int_step(deep_swapper_choices.deep_swapper_morph_range),
31
+ minimum = deep_swapper_choices.deep_swapper_morph_range[0],
32
+ maximum = deep_swapper_choices.deep_swapper_morph_range[-1],
33
+ visible = has_deep_swapper and load_processor_module('deep_swapper').get_inference_pool() and load_processor_module('deep_swapper').has_morph_input()
34
+ )
35
+ register_ui_component('deep_swapper_model_dropdown', DEEP_SWAPPER_MODEL_DROPDOWN)
36
+ register_ui_component('deep_swapper_morph_slider', DEEP_SWAPPER_MORPH_SLIDER)
37
+
38
+
39
+ def listen() -> None:
40
+ DEEP_SWAPPER_MODEL_DROPDOWN.change(update_deep_swapper_model, inputs = DEEP_SWAPPER_MODEL_DROPDOWN, outputs = [ DEEP_SWAPPER_MODEL_DROPDOWN, DEEP_SWAPPER_MORPH_SLIDER ])
41
+ DEEP_SWAPPER_MORPH_SLIDER.release(update_deep_swapper_morph, inputs = DEEP_SWAPPER_MORPH_SLIDER)
42
+
43
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
44
+ if processors_checkbox_group:
45
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ DEEP_SWAPPER_MODEL_DROPDOWN, DEEP_SWAPPER_MORPH_SLIDER ])
46
+
47
+
48
+ def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider]:
49
+ has_deep_swapper = 'deep_swapper' in processors
50
+ return gradio.Dropdown(visible = has_deep_swapper), gradio.Slider(visible = has_deep_swapper and load_processor_module('deep_swapper').get_inference_pool() and load_processor_module('deep_swapper').has_morph_input())
51
+
52
+
53
+ def update_deep_swapper_model(deep_swapper_model : DeepSwapperModel) -> Tuple[gradio.Dropdown, gradio.Slider]:
54
+ deep_swapper_module = load_processor_module('deep_swapper')
55
+ deep_swapper_module.clear_inference_pool()
56
+ state_manager.set_item('deep_swapper_model', deep_swapper_model)
57
+
58
+ if deep_swapper_module.pre_check():
59
+ return gradio.Dropdown(value = state_manager.get_item('deep_swapper_model')), gradio.Slider(visible = deep_swapper_module.has_morph_input())
60
+ return gradio.Dropdown(), gradio.Slider()
61
+
62
+
63
+ def update_deep_swapper_morph(deep_swapper_morph : int) -> None:
64
+ state_manager.set_item('deep_swapper_morph', deep_swapper_morph)
uis/components/download.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import content_analyser, face_classifier, face_detector, face_landmarker, face_masker, face_recognizer, state_manager, translator, voice_extractor
7
+ from facefusion.filesystem import get_file_name, resolve_file_paths
8
+ from facefusion.processors.core import get_processors_modules
9
+ from facefusion.types import DownloadProvider
10
+
11
+ DOWNLOAD_PROVIDERS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
12
+
13
+
14
+ def render() -> None:
15
+ global DOWNLOAD_PROVIDERS_CHECKBOX_GROUP
16
+
17
+ DOWNLOAD_PROVIDERS_CHECKBOX_GROUP = gradio.CheckboxGroup(
18
+ label = translator.get('uis.download_providers_checkbox_group'),
19
+ choices = facefusion.choices.download_providers,
20
+ value = state_manager.get_item('download_providers')
21
+ )
22
+
23
+
24
+ def listen() -> None:
25
+ DOWNLOAD_PROVIDERS_CHECKBOX_GROUP.change(update_download_providers, inputs = DOWNLOAD_PROVIDERS_CHECKBOX_GROUP, outputs = DOWNLOAD_PROVIDERS_CHECKBOX_GROUP)
26
+
27
+
28
+ def update_download_providers(download_providers : List[DownloadProvider]) -> gradio.CheckboxGroup:
29
+ common_modules =\
30
+ [
31
+ content_analyser,
32
+ face_classifier,
33
+ face_detector,
34
+ face_landmarker,
35
+ face_recognizer,
36
+ face_masker,
37
+ voice_extractor
38
+ ]
39
+ available_processors = [ get_file_name(file_path) for file_path in resolve_file_paths('facefusion/processors/modules') ]
40
+ processor_modules = get_processors_modules(available_processors)
41
+
42
+ for module in common_modules + processor_modules:
43
+ if hasattr(module, 'create_static_model_set'):
44
+ module.create_static_model_set.cache_clear()
45
+
46
+ download_providers = download_providers or facefusion.choices.download_providers
47
+ state_manager.set_item('download_providers', download_providers)
48
+ return gradio.CheckboxGroup(value = state_manager.get_item('download_providers'))
uis/components/execution.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional
2
+
3
+ import gradio
4
+
5
+ from facefusion import content_analyser, face_classifier, face_detector, face_landmarker, face_masker, face_recognizer, state_manager, translator, voice_extractor
6
+ from facefusion.execution import get_available_execution_providers
7
+ from facefusion.filesystem import get_file_name, resolve_file_paths
8
+ from facefusion.processors.core import get_processors_modules
9
+ from facefusion.types import ExecutionProvider
10
+
11
+ EXECUTION_PROVIDERS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
12
+
13
+
14
+ def render() -> None:
15
+ global EXECUTION_PROVIDERS_CHECKBOX_GROUP
16
+
17
+ EXECUTION_PROVIDERS_CHECKBOX_GROUP = gradio.CheckboxGroup(
18
+ label = translator.get('uis.execution_providers_checkbox_group'),
19
+ choices = get_available_execution_providers(),
20
+ value = state_manager.get_item('execution_providers')
21
+ )
22
+
23
+
24
+ def listen() -> None:
25
+ EXECUTION_PROVIDERS_CHECKBOX_GROUP.change(update_execution_providers, inputs = EXECUTION_PROVIDERS_CHECKBOX_GROUP, outputs = EXECUTION_PROVIDERS_CHECKBOX_GROUP)
26
+
27
+
28
+ def update_execution_providers(execution_providers : List[ExecutionProvider]) -> gradio.CheckboxGroup:
29
+ common_modules =\
30
+ [
31
+ content_analyser,
32
+ face_classifier,
33
+ face_detector,
34
+ face_landmarker,
35
+ face_masker,
36
+ face_recognizer,
37
+ voice_extractor
38
+ ]
39
+ available_processors = [ get_file_name(file_path) for file_path in resolve_file_paths('facefusion/processors/modules') ]
40
+ processor_modules = get_processors_modules(available_processors)
41
+
42
+ for module in common_modules + processor_modules:
43
+ if hasattr(module, 'clear_inference_pool'):
44
+ module.clear_inference_pool()
45
+
46
+ execution_providers = execution_providers or get_available_execution_providers()
47
+ state_manager.set_item('execution_providers', execution_providers)
48
+ return gradio.CheckboxGroup(value = state_manager.get_item('execution_providers'))
uis/components/execution_thread_count.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import state_manager, translator
7
+ from facefusion.common_helper import calculate_int_step
8
+
9
+ EXECUTION_THREAD_COUNT_SLIDER : Optional[gradio.Slider] = None
10
+
11
+
12
+ def render() -> None:
13
+ global EXECUTION_THREAD_COUNT_SLIDER
14
+
15
+ EXECUTION_THREAD_COUNT_SLIDER = gradio.Slider(
16
+ label = translator.get('uis.execution_thread_count_slider'),
17
+ value = state_manager.get_item('execution_thread_count'),
18
+ step = calculate_int_step(facefusion.choices.execution_thread_count_range),
19
+ minimum = facefusion.choices.execution_thread_count_range[0],
20
+ maximum = facefusion.choices.execution_thread_count_range[-1]
21
+ )
22
+
23
+
24
+ def listen() -> None:
25
+ EXECUTION_THREAD_COUNT_SLIDER.release(update_execution_thread_count, inputs = EXECUTION_THREAD_COUNT_SLIDER)
26
+
27
+
28
+ def update_execution_thread_count(execution_thread_count : float) -> None:
29
+ state_manager.set_item('execution_thread_count', int(execution_thread_count))
uis/components/expression_restorer_options.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.common_helper import calculate_float_step
7
+ from facefusion.processors.core import load_processor_module
8
+ from facefusion.processors.modules.expression_restorer import choices as expression_restorer_choices
9
+ from facefusion.processors.modules.expression_restorer.types import ExpressionRestorerArea, ExpressionRestorerModel
10
+ from facefusion.uis.core import get_ui_component, register_ui_component
11
+
12
+ EXPRESSION_RESTORER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
13
+ EXPRESSION_RESTORER_FACTOR_SLIDER : Optional[gradio.Slider] = None
14
+ EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
15
+
16
+
17
+ def render() -> None:
18
+ global EXPRESSION_RESTORER_MODEL_DROPDOWN
19
+ global EXPRESSION_RESTORER_FACTOR_SLIDER
20
+ global EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP
21
+
22
+ has_expression_restorer = 'expression_restorer' in state_manager.get_item('processors')
23
+ EXPRESSION_RESTORER_MODEL_DROPDOWN = gradio.Dropdown(
24
+ label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.expression_restorer'),
25
+ choices = expression_restorer_choices.expression_restorer_models,
26
+ value = state_manager.get_item('expression_restorer_model'),
27
+ visible = has_expression_restorer
28
+ )
29
+ EXPRESSION_RESTORER_FACTOR_SLIDER = gradio.Slider(
30
+ label = translator.get('uis.factor_slider', 'facefusion.processors.modules.expression_restorer'),
31
+ value = state_manager.get_item('expression_restorer_factor'),
32
+ step = calculate_float_step(expression_restorer_choices.expression_restorer_factor_range),
33
+ minimum = expression_restorer_choices.expression_restorer_factor_range[0],
34
+ maximum = expression_restorer_choices.expression_restorer_factor_range[-1],
35
+ visible = has_expression_restorer
36
+ )
37
+ EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP = gradio.CheckboxGroup(
38
+ label = translator.get('uis.areas_checkbox_group', 'facefusion.processors.modules.expression_restorer'),
39
+ choices = expression_restorer_choices.expression_restorer_areas,
40
+ value = state_manager.get_item('expression_restorer_areas'),
41
+ visible = has_expression_restorer
42
+ )
43
+ register_ui_component('expression_restorer_model_dropdown', EXPRESSION_RESTORER_MODEL_DROPDOWN)
44
+ register_ui_component('expression_restorer_factor_slider', EXPRESSION_RESTORER_FACTOR_SLIDER)
45
+ register_ui_component('expression_restorer_areas_checkbox_group', EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP)
46
+
47
+
48
+ def listen() -> None:
49
+ EXPRESSION_RESTORER_MODEL_DROPDOWN.change(update_expression_restorer_model, inputs = EXPRESSION_RESTORER_MODEL_DROPDOWN, outputs = EXPRESSION_RESTORER_MODEL_DROPDOWN)
50
+ EXPRESSION_RESTORER_FACTOR_SLIDER.release(update_expression_restorer_factor, inputs = EXPRESSION_RESTORER_FACTOR_SLIDER)
51
+ EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP.change(update_expression_restorer_areas, inputs = EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP, outputs = EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP)
52
+
53
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
54
+ if processors_checkbox_group:
55
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ EXPRESSION_RESTORER_MODEL_DROPDOWN, EXPRESSION_RESTORER_FACTOR_SLIDER, EXPRESSION_RESTORER_AREAS_CHECKBOX_GROUP ])
56
+
57
+
58
+ def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider, gradio.CheckboxGroup]:
59
+ has_expression_restorer = 'expression_restorer' in processors
60
+ return gradio.Dropdown(visible = has_expression_restorer), gradio.Slider(visible = has_expression_restorer), gradio.CheckboxGroup(visible = has_expression_restorer)
61
+
62
+
63
+ def update_expression_restorer_model(expression_restorer_model : ExpressionRestorerModel) -> gradio.Dropdown:
64
+ expression_restorer_module = load_processor_module('expression_restorer')
65
+ expression_restorer_module.clear_inference_pool()
66
+ state_manager.set_item('expression_restorer_model', expression_restorer_model)
67
+
68
+ if expression_restorer_module.pre_check():
69
+ return gradio.Dropdown(value = state_manager.get_item('expression_restorer_model'))
70
+ return gradio.Dropdown()
71
+
72
+
73
+ def update_expression_restorer_factor(expression_restorer_factor : float) -> None:
74
+ state_manager.set_item('expression_restorer_factor', int(expression_restorer_factor))
75
+
76
+
77
+ def update_expression_restorer_areas(expression_restorer_areas : List[ExpressionRestorerArea]) -> gradio.CheckboxGroup:
78
+ expression_restorer_areas = expression_restorer_areas or expression_restorer_choices.expression_restorer_areas
79
+ state_manager.set_item('expression_restorer_areas', expression_restorer_areas)
80
+ return gradio.CheckboxGroup(value = state_manager.get_item('expression_restorer_areas'))
uis/components/face_debugger_options.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.processors.modules.face_debugger import choices as face_debugger_choices
7
+ from facefusion.processors.modules.face_debugger.types import FaceDebuggerItem
8
+ from facefusion.uis.core import get_ui_component, register_ui_component
9
+
10
+ FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
11
+
12
+
13
+ def render() -> None:
14
+ global FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP
15
+
16
+ has_face_debugger = 'face_debugger' in state_manager.get_item('processors')
17
+ FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP = gradio.CheckboxGroup(
18
+ label = translator.get('uis.items_checkbox_group', 'facefusion.processors.modules.face_debugger'),
19
+ choices = face_debugger_choices.face_debugger_items,
20
+ value = state_manager.get_item('face_debugger_items'),
21
+ visible = has_face_debugger
22
+ )
23
+ register_ui_component('face_debugger_items_checkbox_group', FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP)
24
+
25
+
26
+ def listen() -> None:
27
+ FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP.change(update_face_debugger_items, inputs = FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP)
28
+
29
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
30
+ if processors_checkbox_group:
31
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = FACE_DEBUGGER_ITEMS_CHECKBOX_GROUP)
32
+
33
+
34
+ def remote_update(processors : List[str]) -> gradio.CheckboxGroup:
35
+ has_face_debugger = 'face_debugger' in processors
36
+ return gradio.CheckboxGroup(visible = has_face_debugger)
37
+
38
+
39
+ def update_face_debugger_items(face_debugger_items : List[FaceDebuggerItem]) -> None:
40
+ state_manager.set_item('face_debugger_items', face_debugger_items)
uis/components/face_detector.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional, Sequence, Tuple
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import face_detector, state_manager, translator
7
+ from facefusion.common_helper import calculate_float_step, get_last
8
+ from facefusion.sanitizer import sanitize_int_range
9
+ from facefusion.types import Angle, FaceDetectorModel, Score
10
+ from facefusion.uis.core import register_ui_component
11
+ from facefusion.uis.types import ComponentOptions
12
+
13
+ FACE_DETECTOR_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
14
+ FACE_DETECTOR_SIZE_DROPDOWN : Optional[gradio.Dropdown] = None
15
+ FACE_DETECTOR_MARGIN_SLIDER : Optional[gradio.Slider] = None
16
+ FACE_DETECTOR_ANGLES_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
17
+ FACE_DETECTOR_SCORE_SLIDER : Optional[gradio.Slider] = None
18
+
19
+
20
+ def render() -> None:
21
+ global FACE_DETECTOR_MODEL_DROPDOWN
22
+ global FACE_DETECTOR_SIZE_DROPDOWN
23
+ global FACE_DETECTOR_MARGIN_SLIDER
24
+ global FACE_DETECTOR_ANGLES_CHECKBOX_GROUP
25
+ global FACE_DETECTOR_SCORE_SLIDER
26
+
27
+ face_detector_size_dropdown_options : ComponentOptions =\
28
+ {
29
+ 'label': translator.get('uis.face_detector_size_dropdown'),
30
+ 'value': state_manager.get_item('face_detector_size')
31
+ }
32
+ if state_manager.get_item('face_detector_size') in facefusion.choices.face_detector_set[state_manager.get_item('face_detector_model')]:
33
+ face_detector_size_dropdown_options['choices'] = facefusion.choices.face_detector_set[state_manager.get_item('face_detector_model')]
34
+ with gradio.Row():
35
+ FACE_DETECTOR_MODEL_DROPDOWN = gradio.Dropdown(
36
+ label = translator.get('uis.face_detector_model_dropdown'),
37
+ choices = facefusion.choices.face_detector_models,
38
+ value = state_manager.get_item('face_detector_model')
39
+ )
40
+ FACE_DETECTOR_SIZE_DROPDOWN = gradio.Dropdown(**face_detector_size_dropdown_options)
41
+ FACE_DETECTOR_MARGIN_SLIDER = gradio.Slider(
42
+ label = translator.get('uis.face_detector_margin_slider'),
43
+ value = state_manager.get_item('face_detector_margin')[0],
44
+ step = calculate_float_step(facefusion.choices.face_detector_margin_range),
45
+ minimum = facefusion.choices.face_detector_margin_range[0],
46
+ maximum = facefusion.choices.face_detector_margin_range[-1]
47
+ )
48
+ FACE_DETECTOR_ANGLES_CHECKBOX_GROUP = gradio.CheckboxGroup(
49
+ label = translator.get('uis.face_detector_angles_checkbox_group'),
50
+ choices = facefusion.choices.face_detector_angles,
51
+ value = state_manager.get_item('face_detector_angles')
52
+ )
53
+ FACE_DETECTOR_SCORE_SLIDER = gradio.Slider(
54
+ label = translator.get('uis.face_detector_score_slider'),
55
+ value = state_manager.get_item('face_detector_score'),
56
+ step = calculate_float_step(facefusion.choices.face_detector_score_range),
57
+ minimum = facefusion.choices.face_detector_score_range[0],
58
+ maximum = facefusion.choices.face_detector_score_range[-1]
59
+ )
60
+ register_ui_component('face_detector_model_dropdown', FACE_DETECTOR_MODEL_DROPDOWN)
61
+ register_ui_component('face_detector_size_dropdown', FACE_DETECTOR_SIZE_DROPDOWN)
62
+ register_ui_component('face_detector_margin_slider', FACE_DETECTOR_MARGIN_SLIDER)
63
+ register_ui_component('face_detector_angles_checkbox_group', FACE_DETECTOR_ANGLES_CHECKBOX_GROUP)
64
+ register_ui_component('face_detector_score_slider', FACE_DETECTOR_SCORE_SLIDER)
65
+
66
+
67
+ def listen() -> None:
68
+ FACE_DETECTOR_MODEL_DROPDOWN.change(update_face_detector_model, inputs = FACE_DETECTOR_MODEL_DROPDOWN, outputs = [ FACE_DETECTOR_MODEL_DROPDOWN, FACE_DETECTOR_SIZE_DROPDOWN ])
69
+ FACE_DETECTOR_SIZE_DROPDOWN.change(update_face_detector_size, inputs = FACE_DETECTOR_SIZE_DROPDOWN)
70
+ FACE_DETECTOR_MARGIN_SLIDER.release(update_face_detector_margin, inputs=FACE_DETECTOR_MARGIN_SLIDER)
71
+ FACE_DETECTOR_ANGLES_CHECKBOX_GROUP.change(update_face_detector_angles, inputs = FACE_DETECTOR_ANGLES_CHECKBOX_GROUP, outputs = FACE_DETECTOR_ANGLES_CHECKBOX_GROUP)
72
+ FACE_DETECTOR_SCORE_SLIDER.release(update_face_detector_score, inputs = FACE_DETECTOR_SCORE_SLIDER)
73
+
74
+
75
+ def update_face_detector_model(face_detector_model : FaceDetectorModel) -> Tuple[gradio.Dropdown, gradio.Dropdown]:
76
+ face_detector.clear_inference_pool()
77
+ state_manager.set_item('face_detector_model', face_detector_model)
78
+
79
+ if face_detector.pre_check():
80
+ face_detector_size_choices = facefusion.choices.face_detector_set.get(state_manager.get_item('face_detector_model'))
81
+ state_manager.set_item('face_detector_size', get_last(face_detector_size_choices))
82
+ return gradio.Dropdown(value = state_manager.get_item('face_detector_model')), gradio.Dropdown(value = state_manager.get_item('face_detector_size'), choices = face_detector_size_choices)
83
+ return gradio.Dropdown(), gradio.Dropdown()
84
+
85
+
86
+ def update_face_detector_size(face_detector_size : str) -> None:
87
+ state_manager.set_item('face_detector_size', face_detector_size)
88
+
89
+
90
+ def update_face_detector_margin(face_detector_margin : int) -> None:
91
+ face_detector_margin = sanitize_int_range(face_detector_margin, facefusion.choices.face_detector_margin_range)
92
+ state_manager.set_item('face_detector_margin', (face_detector_margin, face_detector_margin, face_detector_margin, face_detector_margin))
93
+
94
+
95
+ def update_face_detector_angles(face_detector_angles : Sequence[Angle]) -> gradio.CheckboxGroup:
96
+ face_detector_angles = face_detector_angles or facefusion.choices.face_detector_angles
97
+
98
+ state_manager.set_item('face_detector_angles', face_detector_angles)
99
+ return gradio.CheckboxGroup(value = state_manager.get_item('face_detector_angles'))
100
+
101
+
102
+ def update_face_detector_score(face_detector_score : Score) -> None:
103
+ state_manager.set_item('face_detector_score', face_detector_score)
uis/components/face_editor_options.py ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.common_helper import calculate_float_step
7
+ from facefusion.processors.core import load_processor_module
8
+ from facefusion.processors.modules.face_editor import choices as face_editor_choices
9
+ from facefusion.processors.modules.face_editor.types import FaceEditorModel
10
+ from facefusion.uis.core import get_ui_component, register_ui_component
11
+
12
+ FACE_EDITOR_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
13
+ FACE_EDITOR_EYEBROW_DIRECTION_SLIDER : Optional[gradio.Slider] = None
14
+ FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER : Optional[gradio.Slider] = None
15
+ FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER : Optional[gradio.Slider] = None
16
+ FACE_EDITOR_EYE_OPEN_RATIO_SLIDER : Optional[gradio.Slider] = None
17
+ FACE_EDITOR_LIP_OPEN_RATIO_SLIDER : Optional[gradio.Slider] = None
18
+ FACE_EDITOR_MOUTH_GRIM_SLIDER : Optional[gradio.Slider] = None
19
+ FACE_EDITOR_MOUTH_POUT_SLIDER : Optional[gradio.Slider] = None
20
+ FACE_EDITOR_MOUTH_PURSE_SLIDER : Optional[gradio.Slider] = None
21
+ FACE_EDITOR_MOUTH_SMILE_SLIDER : Optional[gradio.Slider] = None
22
+ FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER : Optional[gradio.Slider] = None
23
+ FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER : Optional[gradio.Slider] = None
24
+ FACE_EDITOR_HEAD_PITCH_SLIDER : Optional[gradio.Slider] = None
25
+ FACE_EDITOR_HEAD_YAW_SLIDER : Optional[gradio.Slider] = None
26
+ FACE_EDITOR_HEAD_ROLL_SLIDER : Optional[gradio.Slider] = None
27
+
28
+
29
+ def render() -> None:
30
+ global FACE_EDITOR_MODEL_DROPDOWN
31
+ global FACE_EDITOR_EYEBROW_DIRECTION_SLIDER
32
+ global FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER
33
+ global FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER
34
+ global FACE_EDITOR_EYE_OPEN_RATIO_SLIDER
35
+ global FACE_EDITOR_LIP_OPEN_RATIO_SLIDER
36
+ global FACE_EDITOR_MOUTH_GRIM_SLIDER
37
+ global FACE_EDITOR_MOUTH_POUT_SLIDER
38
+ global FACE_EDITOR_MOUTH_PURSE_SLIDER
39
+ global FACE_EDITOR_MOUTH_SMILE_SLIDER
40
+ global FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER
41
+ global FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER
42
+ global FACE_EDITOR_HEAD_PITCH_SLIDER
43
+ global FACE_EDITOR_HEAD_YAW_SLIDER
44
+ global FACE_EDITOR_HEAD_ROLL_SLIDER
45
+
46
+ has_face_editor = 'face_editor' in state_manager.get_item('processors')
47
+ FACE_EDITOR_MODEL_DROPDOWN = gradio.Dropdown(
48
+ label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.face_editor'),
49
+ choices = face_editor_choices.face_editor_models,
50
+ value = state_manager.get_item('face_editor_model'),
51
+ visible = has_face_editor
52
+ )
53
+ FACE_EDITOR_EYEBROW_DIRECTION_SLIDER = gradio.Slider(
54
+ label = translator.get('uis.eyebrow_direction_slider', 'facefusion.processors.modules.face_editor'),
55
+ value = state_manager.get_item('face_editor_eyebrow_direction'),
56
+ step = calculate_float_step(face_editor_choices.face_editor_eyebrow_direction_range),
57
+ minimum = face_editor_choices.face_editor_eyebrow_direction_range[0],
58
+ maximum = face_editor_choices.face_editor_eyebrow_direction_range[-1],
59
+ visible = has_face_editor
60
+ )
61
+ FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER = gradio.Slider(
62
+ label = translator.get('uis.eye_gaze_horizontal_slider', 'facefusion.processors.modules.face_editor'),
63
+ value = state_manager.get_item('face_editor_eye_gaze_horizontal'),
64
+ step = calculate_float_step(face_editor_choices.face_editor_eye_gaze_horizontal_range),
65
+ minimum = face_editor_choices.face_editor_eye_gaze_horizontal_range[0],
66
+ maximum = face_editor_choices.face_editor_eye_gaze_horizontal_range[-1],
67
+ visible = has_face_editor
68
+ )
69
+ FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER = gradio.Slider(
70
+ label = translator.get('uis.eye_gaze_vertical_slider', 'facefusion.processors.modules.face_editor'),
71
+ value = state_manager.get_item('face_editor_eye_gaze_vertical'),
72
+ step = calculate_float_step(face_editor_choices.face_editor_eye_gaze_vertical_range),
73
+ minimum = face_editor_choices.face_editor_eye_gaze_vertical_range[0],
74
+ maximum = face_editor_choices.face_editor_eye_gaze_vertical_range[-1],
75
+ visible = has_face_editor
76
+ )
77
+ FACE_EDITOR_EYE_OPEN_RATIO_SLIDER = gradio.Slider(
78
+ label = translator.get('uis.eye_open_ratio_slider', 'facefusion.processors.modules.face_editor'),
79
+ value = state_manager.get_item('face_editor_eye_open_ratio'),
80
+ step = calculate_float_step(face_editor_choices.face_editor_eye_open_ratio_range),
81
+ minimum = face_editor_choices.face_editor_eye_open_ratio_range[0],
82
+ maximum = face_editor_choices.face_editor_eye_open_ratio_range[-1],
83
+ visible = has_face_editor
84
+ )
85
+ FACE_EDITOR_LIP_OPEN_RATIO_SLIDER = gradio.Slider(
86
+ label = translator.get('uis.lip_open_ratio_slider', 'facefusion.processors.modules.face_editor'),
87
+ value = state_manager.get_item('face_editor_lip_open_ratio'),
88
+ step = calculate_float_step(face_editor_choices.face_editor_lip_open_ratio_range),
89
+ minimum = face_editor_choices.face_editor_lip_open_ratio_range[0],
90
+ maximum = face_editor_choices.face_editor_lip_open_ratio_range[-1],
91
+ visible = has_face_editor
92
+ )
93
+ FACE_EDITOR_MOUTH_GRIM_SLIDER = gradio.Slider(
94
+ label = translator.get('uis.mouth_grim_slider', 'facefusion.processors.modules.face_editor'),
95
+ value = state_manager.get_item('face_editor_mouth_grim'),
96
+ step = calculate_float_step(face_editor_choices.face_editor_mouth_grim_range),
97
+ minimum = face_editor_choices.face_editor_mouth_grim_range[0],
98
+ maximum = face_editor_choices.face_editor_mouth_grim_range[-1],
99
+ visible = has_face_editor
100
+ )
101
+ FACE_EDITOR_MOUTH_POUT_SLIDER = gradio.Slider(
102
+ label = translator.get('uis.mouth_pout_slider', 'facefusion.processors.modules.face_editor'),
103
+ value = state_manager.get_item('face_editor_mouth_pout'),
104
+ step = calculate_float_step(face_editor_choices.face_editor_mouth_pout_range),
105
+ minimum = face_editor_choices.face_editor_mouth_pout_range[0],
106
+ maximum = face_editor_choices.face_editor_mouth_pout_range[-1],
107
+ visible = has_face_editor
108
+ )
109
+ FACE_EDITOR_MOUTH_PURSE_SLIDER = gradio.Slider(
110
+ label = translator.get('uis.mouth_purse_slider', 'facefusion.processors.modules.face_editor'),
111
+ value = state_manager.get_item('face_editor_mouth_purse'),
112
+ step = calculate_float_step(face_editor_choices.face_editor_mouth_purse_range),
113
+ minimum = face_editor_choices.face_editor_mouth_purse_range[0],
114
+ maximum = face_editor_choices.face_editor_mouth_purse_range[-1],
115
+ visible = has_face_editor
116
+ )
117
+ FACE_EDITOR_MOUTH_SMILE_SLIDER = gradio.Slider(
118
+ label = translator.get('uis.mouth_smile_slider', 'facefusion.processors.modules.face_editor'),
119
+ value = state_manager.get_item('face_editor_mouth_smile'),
120
+ step = calculate_float_step(face_editor_choices.face_editor_mouth_smile_range),
121
+ minimum = face_editor_choices.face_editor_mouth_smile_range[0],
122
+ maximum = face_editor_choices.face_editor_mouth_smile_range[-1],
123
+ visible = has_face_editor
124
+ )
125
+ FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER = gradio.Slider(
126
+ label = translator.get('uis.mouth_position_horizontal_slider', 'facefusion.processors.modules.face_editor'),
127
+ value = state_manager.get_item('face_editor_mouth_position_horizontal'),
128
+ step = calculate_float_step(face_editor_choices.face_editor_mouth_position_horizontal_range),
129
+ minimum = face_editor_choices.face_editor_mouth_position_horizontal_range[0],
130
+ maximum = face_editor_choices.face_editor_mouth_position_horizontal_range[-1],
131
+ visible = has_face_editor
132
+ )
133
+ FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER = gradio.Slider(
134
+ label = translator.get('uis.mouth_position_vertical_slider', 'facefusion.processors.modules.face_editor'),
135
+ value = state_manager.get_item('face_editor_mouth_position_vertical'),
136
+ step = calculate_float_step(face_editor_choices.face_editor_mouth_position_vertical_range),
137
+ minimum = face_editor_choices.face_editor_mouth_position_vertical_range[0],
138
+ maximum = face_editor_choices.face_editor_mouth_position_vertical_range[-1],
139
+ visible = has_face_editor
140
+ )
141
+ FACE_EDITOR_HEAD_PITCH_SLIDER = gradio.Slider(
142
+ label = translator.get('uis.head_pitch_slider', 'facefusion.processors.modules.face_editor'),
143
+ value = state_manager.get_item('face_editor_head_pitch'),
144
+ step = calculate_float_step(face_editor_choices.face_editor_head_pitch_range),
145
+ minimum = face_editor_choices.face_editor_head_pitch_range[0],
146
+ maximum = face_editor_choices.face_editor_head_pitch_range[-1],
147
+ visible = has_face_editor
148
+ )
149
+ FACE_EDITOR_HEAD_YAW_SLIDER = gradio.Slider(
150
+ label = translator.get('uis.head_yaw_slider', 'facefusion.processors.modules.face_editor'),
151
+ value = state_manager.get_item('face_editor_head_yaw'),
152
+ step = calculate_float_step(face_editor_choices.face_editor_head_yaw_range),
153
+ minimum = face_editor_choices.face_editor_head_yaw_range[0],
154
+ maximum = face_editor_choices.face_editor_head_yaw_range[-1],
155
+ visible = has_face_editor
156
+ )
157
+ FACE_EDITOR_HEAD_ROLL_SLIDER = gradio.Slider(
158
+ label = translator.get('uis.head_roll_slider', 'facefusion.processors.modules.face_editor'),
159
+ value = state_manager.get_item('face_editor_head_roll'),
160
+ step = calculate_float_step(face_editor_choices.face_editor_head_roll_range),
161
+ minimum = face_editor_choices.face_editor_head_roll_range[0],
162
+ maximum = face_editor_choices.face_editor_head_roll_range[-1],
163
+ visible = has_face_editor
164
+ )
165
+ register_ui_component('face_editor_model_dropdown', FACE_EDITOR_MODEL_DROPDOWN)
166
+ register_ui_component('face_editor_eyebrow_direction_slider', FACE_EDITOR_EYEBROW_DIRECTION_SLIDER)
167
+ register_ui_component('face_editor_eye_gaze_horizontal_slider', FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER)
168
+ register_ui_component('face_editor_eye_gaze_vertical_slider', FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER)
169
+ register_ui_component('face_editor_eye_open_ratio_slider', FACE_EDITOR_EYE_OPEN_RATIO_SLIDER)
170
+ register_ui_component('face_editor_lip_open_ratio_slider', FACE_EDITOR_LIP_OPEN_RATIO_SLIDER)
171
+ register_ui_component('face_editor_mouth_grim_slider', FACE_EDITOR_MOUTH_GRIM_SLIDER)
172
+ register_ui_component('face_editor_mouth_pout_slider', FACE_EDITOR_MOUTH_POUT_SLIDER)
173
+ register_ui_component('face_editor_mouth_purse_slider', FACE_EDITOR_MOUTH_PURSE_SLIDER)
174
+ register_ui_component('face_editor_mouth_smile_slider', FACE_EDITOR_MOUTH_SMILE_SLIDER)
175
+ register_ui_component('face_editor_mouth_position_horizontal_slider', FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER)
176
+ register_ui_component('face_editor_mouth_position_vertical_slider', FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER)
177
+ register_ui_component('face_editor_head_pitch_slider', FACE_EDITOR_HEAD_PITCH_SLIDER)
178
+ register_ui_component('face_editor_head_yaw_slider', FACE_EDITOR_HEAD_YAW_SLIDER)
179
+ register_ui_component('face_editor_head_roll_slider', FACE_EDITOR_HEAD_ROLL_SLIDER)
180
+
181
+
182
+ def listen() -> None:
183
+ FACE_EDITOR_MODEL_DROPDOWN.change(update_face_editor_model, inputs = FACE_EDITOR_MODEL_DROPDOWN, outputs = FACE_EDITOR_MODEL_DROPDOWN)
184
+ FACE_EDITOR_EYEBROW_DIRECTION_SLIDER.release(update_face_editor_eyebrow_direction, inputs = FACE_EDITOR_EYEBROW_DIRECTION_SLIDER)
185
+ FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER.release(update_face_editor_eye_gaze_horizontal, inputs = FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER)
186
+ FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER.release(update_face_editor_eye_gaze_vertical, inputs = FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER)
187
+ FACE_EDITOR_EYE_OPEN_RATIO_SLIDER.release(update_face_editor_eye_open_ratio, inputs = FACE_EDITOR_EYE_OPEN_RATIO_SLIDER)
188
+ FACE_EDITOR_LIP_OPEN_RATIO_SLIDER.release(update_face_editor_lip_open_ratio, inputs = FACE_EDITOR_LIP_OPEN_RATIO_SLIDER)
189
+ FACE_EDITOR_MOUTH_GRIM_SLIDER.release(update_face_editor_mouth_grim, inputs = FACE_EDITOR_MOUTH_GRIM_SLIDER)
190
+ FACE_EDITOR_MOUTH_POUT_SLIDER.release(update_face_editor_mouth_pout, inputs = FACE_EDITOR_MOUTH_POUT_SLIDER)
191
+ FACE_EDITOR_MOUTH_PURSE_SLIDER.release(update_face_editor_mouth_purse, inputs = FACE_EDITOR_MOUTH_PURSE_SLIDER)
192
+ FACE_EDITOR_MOUTH_SMILE_SLIDER.release(update_face_editor_mouth_smile, inputs = FACE_EDITOR_MOUTH_SMILE_SLIDER)
193
+ FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER.release(update_face_editor_mouth_position_horizontal, inputs = FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER)
194
+ FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER.release(update_face_editor_mouth_position_vertical, inputs = FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER)
195
+ FACE_EDITOR_HEAD_PITCH_SLIDER.release(update_face_editor_head_pitch, inputs = FACE_EDITOR_HEAD_PITCH_SLIDER)
196
+ FACE_EDITOR_HEAD_YAW_SLIDER.release(update_face_editor_head_yaw, inputs = FACE_EDITOR_HEAD_YAW_SLIDER)
197
+ FACE_EDITOR_HEAD_ROLL_SLIDER.release(update_face_editor_head_roll, inputs = FACE_EDITOR_HEAD_ROLL_SLIDER)
198
+
199
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
200
+ if processors_checkbox_group:
201
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ FACE_EDITOR_MODEL_DROPDOWN, FACE_EDITOR_EYEBROW_DIRECTION_SLIDER, FACE_EDITOR_EYE_GAZE_HORIZONTAL_SLIDER, FACE_EDITOR_EYE_GAZE_VERTICAL_SLIDER, FACE_EDITOR_EYE_OPEN_RATIO_SLIDER, FACE_EDITOR_LIP_OPEN_RATIO_SLIDER, FACE_EDITOR_MOUTH_GRIM_SLIDER, FACE_EDITOR_MOUTH_POUT_SLIDER, FACE_EDITOR_MOUTH_PURSE_SLIDER, FACE_EDITOR_MOUTH_SMILE_SLIDER, FACE_EDITOR_MOUTH_POSITION_HORIZONTAL_SLIDER, FACE_EDITOR_MOUTH_POSITION_VERTICAL_SLIDER, FACE_EDITOR_HEAD_PITCH_SLIDER, FACE_EDITOR_HEAD_YAW_SLIDER, FACE_EDITOR_HEAD_ROLL_SLIDER ])
202
+
203
+
204
+ def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider, gradio.Slider]:
205
+ has_face_editor = 'face_editor' in processors
206
+ return gradio.Dropdown(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor), gradio.Slider(visible = has_face_editor)
207
+
208
+
209
+ def update_face_editor_model(face_editor_model : FaceEditorModel) -> gradio.Dropdown:
210
+ face_editor_module = load_processor_module('face_editor')
211
+ face_editor_module.clear_inference_pool()
212
+ state_manager.set_item('face_editor_model', face_editor_model)
213
+
214
+ if face_editor_module.pre_check():
215
+ return gradio.Dropdown(value = state_manager.get_item('face_editor_model'))
216
+ return gradio.Dropdown()
217
+
218
+
219
+ def update_face_editor_eyebrow_direction(face_editor_eyebrow_direction : float) -> None:
220
+ state_manager.set_item('face_editor_eyebrow_direction', face_editor_eyebrow_direction)
221
+
222
+
223
+ def update_face_editor_eye_gaze_horizontal(face_editor_eye_gaze_horizontal : float) -> None:
224
+ state_manager.set_item('face_editor_eye_gaze_horizontal', face_editor_eye_gaze_horizontal)
225
+
226
+
227
+ def update_face_editor_eye_gaze_vertical(face_editor_eye_gaze_vertical : float) -> None:
228
+ state_manager.set_item('face_editor_eye_gaze_vertical', face_editor_eye_gaze_vertical)
229
+
230
+
231
+ def update_face_editor_eye_open_ratio(face_editor_eye_open_ratio : float) -> None:
232
+ state_manager.set_item('face_editor_eye_open_ratio', face_editor_eye_open_ratio)
233
+
234
+
235
+ def update_face_editor_lip_open_ratio(face_editor_lip_open_ratio : float) -> None:
236
+ state_manager.set_item('face_editor_lip_open_ratio', face_editor_lip_open_ratio)
237
+
238
+
239
+ def update_face_editor_mouth_grim(face_editor_mouth_grim : float) -> None:
240
+ state_manager.set_item('face_editor_mouth_grim', face_editor_mouth_grim)
241
+
242
+
243
+ def update_face_editor_mouth_pout(face_editor_mouth_pout : float) -> None:
244
+ state_manager.set_item('face_editor_mouth_pout', face_editor_mouth_pout)
245
+
246
+
247
+ def update_face_editor_mouth_purse(face_editor_mouth_purse : float) -> None:
248
+ state_manager.set_item('face_editor_mouth_purse', face_editor_mouth_purse)
249
+
250
+
251
+ def update_face_editor_mouth_smile(face_editor_mouth_smile : float) -> None:
252
+ state_manager.set_item('face_editor_mouth_smile', face_editor_mouth_smile)
253
+
254
+
255
+ def update_face_editor_mouth_position_horizontal(face_editor_mouth_position_horizontal : float) -> None:
256
+ state_manager.set_item('face_editor_mouth_position_horizontal', face_editor_mouth_position_horizontal)
257
+
258
+
259
+ def update_face_editor_mouth_position_vertical(face_editor_mouth_position_vertical : float) -> None:
260
+ state_manager.set_item('face_editor_mouth_position_vertical', face_editor_mouth_position_vertical)
261
+
262
+
263
+ def update_face_editor_head_pitch(face_editor_head_pitch : float) -> None:
264
+ state_manager.set_item('face_editor_head_pitch', face_editor_head_pitch)
265
+
266
+
267
+ def update_face_editor_head_yaw(face_editor_head_yaw : float) -> None:
268
+ state_manager.set_item('face_editor_head_yaw', face_editor_head_yaw)
269
+
270
+
271
+ def update_face_editor_head_roll(face_editor_head_roll : float) -> None:
272
+ state_manager.set_item('face_editor_head_roll', face_editor_head_roll)
uis/components/face_enhancer_options.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.common_helper import calculate_float_step, calculate_int_step
7
+ from facefusion.processors.core import load_processor_module
8
+ from facefusion.processors.modules.face_enhancer import choices as face_enhancer_choices
9
+ from facefusion.processors.modules.face_enhancer.types import FaceEnhancerModel, FaceEnhancerWeight
10
+ from facefusion.uis.core import get_ui_component, register_ui_component
11
+
12
+ FACE_ENHANCER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
13
+ FACE_ENHANCER_BLEND_SLIDER : Optional[gradio.Slider] = None
14
+ FACE_ENHANCER_WEIGHT_SLIDER : Optional[gradio.Slider] = None
15
+
16
+
17
+ def render() -> None:
18
+ global FACE_ENHANCER_MODEL_DROPDOWN
19
+ global FACE_ENHANCER_BLEND_SLIDER
20
+ global FACE_ENHANCER_WEIGHT_SLIDER
21
+
22
+ has_face_enhancer = 'face_enhancer' in state_manager.get_item('processors')
23
+ FACE_ENHANCER_MODEL_DROPDOWN = gradio.Dropdown(
24
+ label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.face_enhancer'),
25
+ choices = face_enhancer_choices.face_enhancer_models,
26
+ value = state_manager.get_item('face_enhancer_model'),
27
+ visible = has_face_enhancer
28
+ )
29
+ FACE_ENHANCER_BLEND_SLIDER = gradio.Slider(
30
+ label = translator.get('uis.blend_slider', 'facefusion.processors.modules.face_enhancer'),
31
+ value = state_manager.get_item('face_enhancer_blend'),
32
+ step = calculate_int_step(face_enhancer_choices.face_enhancer_blend_range),
33
+ minimum = face_enhancer_choices.face_enhancer_blend_range[0],
34
+ maximum = face_enhancer_choices.face_enhancer_blend_range[-1],
35
+ visible = has_face_enhancer
36
+ )
37
+ FACE_ENHANCER_WEIGHT_SLIDER = gradio.Slider(
38
+ label = translator.get('uis.weight_slider', 'facefusion.processors.modules.face_enhancer'),
39
+ value = state_manager.get_item('face_enhancer_weight'),
40
+ step = calculate_float_step(face_enhancer_choices.face_enhancer_weight_range),
41
+ minimum = face_enhancer_choices.face_enhancer_weight_range[0],
42
+ maximum = face_enhancer_choices.face_enhancer_weight_range[-1],
43
+ visible = has_face_enhancer and load_processor_module('face_enhancer').get_inference_pool() and load_processor_module('face_enhancer').has_weight_input()
44
+ )
45
+ register_ui_component('face_enhancer_model_dropdown', FACE_ENHANCER_MODEL_DROPDOWN)
46
+ register_ui_component('face_enhancer_blend_slider', FACE_ENHANCER_BLEND_SLIDER)
47
+ register_ui_component('face_enhancer_weight_slider', FACE_ENHANCER_WEIGHT_SLIDER)
48
+
49
+
50
+ def listen() -> None:
51
+ FACE_ENHANCER_MODEL_DROPDOWN.change(update_face_enhancer_model, inputs = FACE_ENHANCER_MODEL_DROPDOWN, outputs = [ FACE_ENHANCER_MODEL_DROPDOWN, FACE_ENHANCER_WEIGHT_SLIDER ])
52
+ FACE_ENHANCER_BLEND_SLIDER.release(update_face_enhancer_blend, inputs = FACE_ENHANCER_BLEND_SLIDER)
53
+ FACE_ENHANCER_WEIGHT_SLIDER.release(update_face_enhancer_weight, inputs = FACE_ENHANCER_WEIGHT_SLIDER)
54
+
55
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
56
+ if processors_checkbox_group:
57
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ FACE_ENHANCER_MODEL_DROPDOWN, FACE_ENHANCER_BLEND_SLIDER, FACE_ENHANCER_WEIGHT_SLIDER ])
58
+
59
+
60
+ def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider, gradio.Slider]:
61
+ has_face_enhancer = 'face_enhancer' in processors
62
+ return gradio.Dropdown(visible = has_face_enhancer), gradio.Slider(visible = has_face_enhancer), gradio.Slider(visible = has_face_enhancer and load_processor_module('face_enhancer').get_inference_pool() and load_processor_module('face_enhancer').has_weight_input())
63
+
64
+
65
+ def update_face_enhancer_model(face_enhancer_model : FaceEnhancerModel) -> Tuple[gradio.Dropdown, gradio.Slider]:
66
+ face_enhancer_module = load_processor_module('face_enhancer')
67
+ face_enhancer_module.clear_inference_pool()
68
+ state_manager.set_item('face_enhancer_model', face_enhancer_model)
69
+
70
+ if face_enhancer_module.pre_check():
71
+ return gradio.Dropdown(value = state_manager.get_item('face_enhancer_model')), gradio.Slider(visible = face_enhancer_module.has_weight_input())
72
+ return gradio.Dropdown(), gradio.Slider()
73
+
74
+
75
+ def update_face_enhancer_blend(face_enhancer_blend : float) -> None:
76
+ state_manager.set_item('face_enhancer_blend', int(face_enhancer_blend))
77
+
78
+
79
+ def update_face_enhancer_weight(face_enhancer_weight : FaceEnhancerWeight) -> None:
80
+ state_manager.set_item('face_enhancer_weight', face_enhancer_weight)
81
+
uis/components/face_landmarker.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import face_landmarker, state_manager, translator
7
+ from facefusion.common_helper import calculate_float_step
8
+ from facefusion.types import FaceLandmarkerModel, Score
9
+ from facefusion.uis.core import register_ui_component
10
+
11
+ FACE_LANDMARKER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
12
+ FACE_LANDMARKER_SCORE_SLIDER : Optional[gradio.Slider] = None
13
+
14
+
15
+ def render() -> None:
16
+ global FACE_LANDMARKER_MODEL_DROPDOWN
17
+ global FACE_LANDMARKER_SCORE_SLIDER
18
+
19
+ FACE_LANDMARKER_MODEL_DROPDOWN = gradio.Dropdown(
20
+ label = translator.get('uis.face_landmarker_model_dropdown'),
21
+ choices = facefusion.choices.face_landmarker_models,
22
+ value = state_manager.get_item('face_landmarker_model')
23
+ )
24
+ FACE_LANDMARKER_SCORE_SLIDER = gradio.Slider(
25
+ label = translator.get('uis.face_landmarker_score_slider'),
26
+ value = state_manager.get_item('face_landmarker_score'),
27
+ step = calculate_float_step(facefusion.choices.face_landmarker_score_range),
28
+ minimum = facefusion.choices.face_landmarker_score_range[0],
29
+ maximum = facefusion.choices.face_landmarker_score_range[-1]
30
+ )
31
+ register_ui_component('face_landmarker_model_dropdown', FACE_LANDMARKER_MODEL_DROPDOWN)
32
+ register_ui_component('face_landmarker_score_slider', FACE_LANDMARKER_SCORE_SLIDER)
33
+
34
+
35
+ def listen() -> None:
36
+ FACE_LANDMARKER_MODEL_DROPDOWN.change(update_face_landmarker_model, inputs = FACE_LANDMARKER_MODEL_DROPDOWN, outputs = FACE_LANDMARKER_MODEL_DROPDOWN)
37
+ FACE_LANDMARKER_SCORE_SLIDER.release(update_face_landmarker_score, inputs = FACE_LANDMARKER_SCORE_SLIDER)
38
+
39
+
40
+ def update_face_landmarker_model(face_landmarker_model : FaceLandmarkerModel) -> gradio.Dropdown:
41
+ face_landmarker.clear_inference_pool()
42
+ state_manager.set_item('face_landmarker_model', face_landmarker_model)
43
+
44
+ if face_landmarker.pre_check():
45
+ gradio.Dropdown(value = state_manager.get_item('face_landmarker_model'))
46
+ return gradio.Dropdown()
47
+
48
+
49
+ def update_face_landmarker_score(face_landmarker_score : Score) -> None:
50
+ state_manager.set_item('face_landmarker_score', face_landmarker_score)
uis/components/face_masker.py ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import face_masker, state_manager, translator
7
+ from facefusion.common_helper import calculate_float_step, calculate_int_step
8
+ from facefusion.sanitizer import sanitize_int_range
9
+ from facefusion.types import FaceMaskArea, FaceMaskRegion, FaceMaskType, FaceOccluderModel, FaceParserModel
10
+ from facefusion.uis.core import register_ui_component
11
+
12
+ FACE_OCCLUDER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
13
+ FACE_PARSER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
14
+ FACE_MASK_TYPES_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
15
+ FACE_MASK_AREAS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
16
+ FACE_MASK_REGIONS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
17
+ FACE_MASK_BOX_WRAPPER : Optional[gradio.Group] = None
18
+ FACE_MASK_BLUR_SLIDER : Optional[gradio.Slider] = None
19
+ FACE_MASK_PADDING_TOP_SLIDER : Optional[gradio.Slider] = None
20
+ FACE_MASK_PADDING_RIGHT_SLIDER : Optional[gradio.Slider] = None
21
+ FACE_MASK_PADDING_BOTTOM_SLIDER : Optional[gradio.Slider] = None
22
+ FACE_MASK_PADDING_LEFT_SLIDER : Optional[gradio.Slider] = None
23
+
24
+
25
+ def render() -> None:
26
+ global FACE_OCCLUDER_MODEL_DROPDOWN
27
+ global FACE_PARSER_MODEL_DROPDOWN
28
+ global FACE_MASK_TYPES_CHECKBOX_GROUP
29
+ global FACE_MASK_AREAS_CHECKBOX_GROUP
30
+ global FACE_MASK_REGIONS_CHECKBOX_GROUP
31
+ global FACE_MASK_BOX_WRAPPER
32
+ global FACE_MASK_BLUR_SLIDER
33
+ global FACE_MASK_PADDING_TOP_SLIDER
34
+ global FACE_MASK_PADDING_RIGHT_SLIDER
35
+ global FACE_MASK_PADDING_BOTTOM_SLIDER
36
+ global FACE_MASK_PADDING_LEFT_SLIDER
37
+
38
+ has_box_mask = 'box' in state_manager.get_item('face_mask_types')
39
+ has_region_mask = 'region' in state_manager.get_item('face_mask_types')
40
+ has_area_mask = 'area' in state_manager.get_item('face_mask_types')
41
+ with gradio.Row():
42
+ FACE_OCCLUDER_MODEL_DROPDOWN = gradio.Dropdown(
43
+ label = translator.get('uis.face_occluder_model_dropdown'),
44
+ choices = facefusion.choices.face_occluder_models,
45
+ value = state_manager.get_item('face_occluder_model')
46
+ )
47
+ FACE_PARSER_MODEL_DROPDOWN = gradio.Dropdown(
48
+ label = translator.get('uis.face_parser_model_dropdown'),
49
+ choices = facefusion.choices.face_parser_models,
50
+ value = state_manager.get_item('face_parser_model')
51
+ )
52
+ FACE_MASK_TYPES_CHECKBOX_GROUP = gradio.CheckboxGroup(
53
+ label = translator.get('uis.face_mask_types_checkbox_group'),
54
+ choices = facefusion.choices.face_mask_types,
55
+ value = state_manager.get_item('face_mask_types')
56
+ )
57
+ FACE_MASK_AREAS_CHECKBOX_GROUP = gradio.CheckboxGroup(
58
+ label = translator.get('uis.face_mask_areas_checkbox_group'),
59
+ choices = facefusion.choices.face_mask_areas,
60
+ value = state_manager.get_item('face_mask_areas'),
61
+ visible = has_area_mask
62
+ )
63
+ FACE_MASK_REGIONS_CHECKBOX_GROUP = gradio.CheckboxGroup(
64
+ label = translator.get('uis.face_mask_regions_checkbox_group'),
65
+ choices = facefusion.choices.face_mask_regions,
66
+ value = state_manager.get_item('face_mask_regions'),
67
+ visible = has_region_mask
68
+ )
69
+ FACE_MASK_BLUR_SLIDER = gradio.Slider(
70
+ label = translator.get('uis.face_mask_blur_slider'),
71
+ step = calculate_float_step(facefusion.choices.face_mask_blur_range),
72
+ minimum = facefusion.choices.face_mask_blur_range[0],
73
+ maximum = facefusion.choices.face_mask_blur_range[-1],
74
+ value = state_manager.get_item('face_mask_blur'),
75
+ visible = has_box_mask
76
+ )
77
+ with gradio.Group(visible = has_box_mask) as FACE_MASK_BOX_WRAPPER:
78
+ with gradio.Row():
79
+ FACE_MASK_PADDING_TOP_SLIDER = gradio.Slider(
80
+ label = translator.get('uis.face_mask_padding_top_slider'),
81
+ step = calculate_int_step(facefusion.choices.face_mask_padding_range),
82
+ minimum = facefusion.choices.face_mask_padding_range[0],
83
+ maximum = facefusion.choices.face_mask_padding_range[-1],
84
+ value = state_manager.get_item('face_mask_padding')[0]
85
+ )
86
+ FACE_MASK_PADDING_RIGHT_SLIDER = gradio.Slider(
87
+ label = translator.get('uis.face_mask_padding_right_slider'),
88
+ step = calculate_int_step(facefusion.choices.face_mask_padding_range),
89
+ minimum = facefusion.choices.face_mask_padding_range[0],
90
+ maximum = facefusion.choices.face_mask_padding_range[-1],
91
+ value = state_manager.get_item('face_mask_padding')[1]
92
+ )
93
+ with gradio.Row():
94
+ FACE_MASK_PADDING_BOTTOM_SLIDER = gradio.Slider(
95
+ label = translator.get('uis.face_mask_padding_bottom_slider'),
96
+ step = calculate_int_step(facefusion.choices.face_mask_padding_range),
97
+ minimum = facefusion.choices.face_mask_padding_range[0],
98
+ maximum = facefusion.choices.face_mask_padding_range[-1],
99
+ value = state_manager.get_item('face_mask_padding')[2]
100
+ )
101
+ FACE_MASK_PADDING_LEFT_SLIDER = gradio.Slider(
102
+ label = translator.get('uis.face_mask_padding_left_slider'),
103
+ step = calculate_int_step(facefusion.choices.face_mask_padding_range),
104
+ minimum = facefusion.choices.face_mask_padding_range[0],
105
+ maximum = facefusion.choices.face_mask_padding_range[-1],
106
+ value = state_manager.get_item('face_mask_padding')[3]
107
+ )
108
+ register_ui_component('face_occluder_model_dropdown', FACE_OCCLUDER_MODEL_DROPDOWN)
109
+ register_ui_component('face_parser_model_dropdown', FACE_PARSER_MODEL_DROPDOWN)
110
+ register_ui_component('face_mask_types_checkbox_group', FACE_MASK_TYPES_CHECKBOX_GROUP)
111
+ register_ui_component('face_mask_areas_checkbox_group', FACE_MASK_AREAS_CHECKBOX_GROUP)
112
+ register_ui_component('face_mask_regions_checkbox_group', FACE_MASK_REGIONS_CHECKBOX_GROUP)
113
+ register_ui_component('face_mask_blur_slider', FACE_MASK_BLUR_SLIDER)
114
+ register_ui_component('face_mask_padding_top_slider', FACE_MASK_PADDING_TOP_SLIDER)
115
+ register_ui_component('face_mask_padding_right_slider', FACE_MASK_PADDING_RIGHT_SLIDER)
116
+ register_ui_component('face_mask_padding_bottom_slider', FACE_MASK_PADDING_BOTTOM_SLIDER)
117
+ register_ui_component('face_mask_padding_left_slider', FACE_MASK_PADDING_LEFT_SLIDER)
118
+
119
+
120
+ def listen() -> None:
121
+ FACE_OCCLUDER_MODEL_DROPDOWN.change(update_face_occluder_model, inputs = FACE_OCCLUDER_MODEL_DROPDOWN)
122
+ FACE_PARSER_MODEL_DROPDOWN.change(update_face_parser_model, inputs = FACE_PARSER_MODEL_DROPDOWN)
123
+ FACE_MASK_TYPES_CHECKBOX_GROUP.change(update_face_mask_types, inputs = FACE_MASK_TYPES_CHECKBOX_GROUP, outputs = [ FACE_MASK_TYPES_CHECKBOX_GROUP, FACE_MASK_AREAS_CHECKBOX_GROUP, FACE_MASK_REGIONS_CHECKBOX_GROUP, FACE_MASK_BLUR_SLIDER, FACE_MASK_BOX_WRAPPER ])
124
+ FACE_MASK_AREAS_CHECKBOX_GROUP.change(update_face_mask_areas, inputs = FACE_MASK_AREAS_CHECKBOX_GROUP, outputs = FACE_MASK_AREAS_CHECKBOX_GROUP)
125
+ FACE_MASK_REGIONS_CHECKBOX_GROUP.change(update_face_mask_regions, inputs = FACE_MASK_REGIONS_CHECKBOX_GROUP, outputs = FACE_MASK_REGIONS_CHECKBOX_GROUP)
126
+ FACE_MASK_BLUR_SLIDER.release(update_face_mask_blur, inputs = FACE_MASK_BLUR_SLIDER)
127
+
128
+ face_mask_padding_sliders = [ FACE_MASK_PADDING_TOP_SLIDER, FACE_MASK_PADDING_RIGHT_SLIDER, FACE_MASK_PADDING_BOTTOM_SLIDER, FACE_MASK_PADDING_LEFT_SLIDER ]
129
+ for face_mask_padding_slider in face_mask_padding_sliders:
130
+ face_mask_padding_slider.release(update_face_mask_padding, inputs = face_mask_padding_sliders)
131
+
132
+
133
+ def update_face_occluder_model(face_occluder_model : FaceOccluderModel) -> gradio.Dropdown:
134
+ face_masker.clear_inference_pool()
135
+ state_manager.set_item('face_occluder_model', face_occluder_model)
136
+
137
+ if face_masker.pre_check():
138
+ return gradio.Dropdown(value = state_manager.get_item('face_occluder_model'))
139
+ return gradio.Dropdown()
140
+
141
+
142
+ def update_face_parser_model(face_parser_model : FaceParserModel) -> gradio.Dropdown:
143
+ face_masker.clear_inference_pool()
144
+ state_manager.set_item('face_parser_model', face_parser_model)
145
+
146
+ if face_masker.pre_check():
147
+ return gradio.Dropdown(value = state_manager.get_item('face_parser_model'))
148
+ return gradio.Dropdown()
149
+
150
+
151
+ def update_face_mask_types(face_mask_types : List[FaceMaskType]) -> Tuple[gradio.CheckboxGroup, gradio.CheckboxGroup, gradio.CheckboxGroup, gradio.Slider, gradio.Group]:
152
+ face_mask_types = face_mask_types or facefusion.choices.face_mask_types
153
+ state_manager.set_item('face_mask_types', face_mask_types)
154
+ has_box_mask = 'box' in face_mask_types
155
+ has_area_mask = 'area' in face_mask_types
156
+ has_region_mask = 'region' in face_mask_types
157
+ return gradio.CheckboxGroup(value = state_manager.get_item('face_mask_types')), gradio.CheckboxGroup(visible = has_area_mask), gradio.CheckboxGroup(visible = has_region_mask), gradio.Slider(visible = has_box_mask), gradio.Group(visible = has_box_mask)
158
+
159
+
160
+ def update_face_mask_areas(face_mask_areas : List[FaceMaskArea]) -> gradio.CheckboxGroup:
161
+ face_mask_areas = face_mask_areas or facefusion.choices.face_mask_areas
162
+ state_manager.set_item('face_mask_areas', face_mask_areas)
163
+ return gradio.CheckboxGroup(value = state_manager.get_item('face_mask_areas'))
164
+
165
+
166
+ def update_face_mask_regions(face_mask_regions : List[FaceMaskRegion]) -> gradio.CheckboxGroup:
167
+ face_mask_regions = face_mask_regions or facefusion.choices.face_mask_regions
168
+ state_manager.set_item('face_mask_regions', face_mask_regions)
169
+ return gradio.CheckboxGroup(value = state_manager.get_item('face_mask_regions'))
170
+
171
+
172
+ def update_face_mask_blur(face_mask_blur : float) -> None:
173
+ state_manager.set_item('face_mask_blur', face_mask_blur)
174
+
175
+
176
+ def update_face_mask_padding(face_mask_padding_top : float, face_mask_padding_right : float, face_mask_padding_bottom : float, face_mask_padding_left : float) -> None:
177
+ face_mask_padding_top = sanitize_int_range(int(face_mask_padding_top), facefusion.choices.face_mask_padding_range)
178
+ face_mask_padding_right = sanitize_int_range(int(face_mask_padding_right), facefusion.choices.face_mask_padding_range)
179
+ face_mask_padding_bottom = sanitize_int_range(int(face_mask_padding_bottom), facefusion.choices.face_mask_padding_range)
180
+ face_mask_padding_left = sanitize_int_range(int(face_mask_padding_left), facefusion.choices.face_mask_padding_range)
181
+ state_manager.set_item('face_mask_padding', (face_mask_padding_top, face_mask_padding_right, face_mask_padding_bottom, face_mask_padding_left))
uis/components/face_selector.py ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import cv2
4
+ import gradio
5
+ from gradio_rangeslider import RangeSlider
6
+
7
+ import facefusion.choices
8
+ from facefusion import state_manager, translator
9
+ from facefusion.common_helper import calculate_float_step, calculate_int_step
10
+ from facefusion.face_creator import get_many_faces
11
+ from facefusion.face_selector import sort_and_filter_faces
12
+ from facefusion.face_store import clear_faces
13
+ from facefusion.filesystem import filter_image_paths, is_image, is_video
14
+ from facefusion.types import FaceSelectorGender, FaceSelectorMode, FaceSelectorOrder, FaceSelectorRace, VisionFrame
15
+ from facefusion.uis.core import get_ui_component, get_ui_components, register_ui_component
16
+ from facefusion.uis.types import ComponentOptions
17
+ from facefusion.uis.ui_helper import convert_str_none
18
+ from facefusion.vision import fit_cover_frame, read_static_image, read_static_images, read_video_frame
19
+
20
+ FACE_SELECTOR_MODE_DROPDOWN : Optional[gradio.Dropdown] = None
21
+ FACE_SELECTOR_ORDER_DROPDOWN : Optional[gradio.Dropdown] = None
22
+ FACE_SELECTOR_GENDER_DROPDOWN : Optional[gradio.Dropdown] = None
23
+ FACE_SELECTOR_RACE_DROPDOWN : Optional[gradio.Dropdown] = None
24
+ FACE_SELECTOR_AGE_RANGE_SLIDER : Optional[RangeSlider] = None
25
+ REFERENCE_FACE_POSITION_GALLERY : Optional[gradio.Gallery] = None
26
+ REFERENCE_FACE_DISTANCE_SLIDER : Optional[gradio.Slider] = None
27
+
28
+
29
+ def render() -> None:
30
+ global FACE_SELECTOR_MODE_DROPDOWN
31
+ global FACE_SELECTOR_ORDER_DROPDOWN
32
+ global FACE_SELECTOR_GENDER_DROPDOWN
33
+ global FACE_SELECTOR_RACE_DROPDOWN
34
+ global FACE_SELECTOR_AGE_RANGE_SLIDER
35
+ global REFERENCE_FACE_POSITION_GALLERY
36
+ global REFERENCE_FACE_DISTANCE_SLIDER
37
+
38
+ reference_face_gallery_options : ComponentOptions =\
39
+ {
40
+ 'label': translator.get('uis.reference_face_gallery'),
41
+ 'object_fit': 'cover',
42
+ 'allow_preview': False,
43
+ 'elem_classes': 'box-face-selector',
44
+ 'visible': 'reference' in state_manager.get_item('face_selector_mode')
45
+ }
46
+ source_vision_frames = read_static_images(filter_image_paths(state_manager.get_item('source_paths')))
47
+
48
+ if is_image(state_manager.get_item('target_path')):
49
+ target_vision_frame = read_static_image(state_manager.get_item('target_path'))
50
+ reference_face_gallery_options['value'] = extract_gallery_frames(source_vision_frames, target_vision_frame)
51
+ if is_video(state_manager.get_item('target_path')):
52
+ target_vision_frame = read_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
53
+ reference_face_gallery_options['value'] = extract_gallery_frames(source_vision_frames, target_vision_frame)
54
+ FACE_SELECTOR_MODE_DROPDOWN = gradio.Dropdown(
55
+ label = translator.get('uis.face_selector_mode_dropdown'),
56
+ choices = facefusion.choices.face_selector_modes,
57
+ value = state_manager.get_item('face_selector_mode')
58
+ )
59
+ REFERENCE_FACE_POSITION_GALLERY = gradio.Gallery(**reference_face_gallery_options)
60
+ with gradio.Group():
61
+ with gradio.Row():
62
+ FACE_SELECTOR_ORDER_DROPDOWN = gradio.Dropdown(
63
+ label = translator.get('uis.face_selector_order_dropdown'),
64
+ choices = facefusion.choices.face_selector_orders,
65
+ value = state_manager.get_item('face_selector_order')
66
+ )
67
+ FACE_SELECTOR_GENDER_DROPDOWN = gradio.Dropdown(
68
+ label = translator.get('uis.face_selector_gender_dropdown'),
69
+ choices = [ 'none' ] + facefusion.choices.face_selector_genders,
70
+ value = state_manager.get_item('face_selector_gender') or 'none'
71
+ )
72
+ FACE_SELECTOR_RACE_DROPDOWN = gradio.Dropdown(
73
+ label = translator.get('uis.face_selector_race_dropdown'),
74
+ choices = [ 'none' ] + facefusion.choices.face_selector_races,
75
+ value = state_manager.get_item('face_selector_race') or 'none'
76
+ )
77
+ with gradio.Row():
78
+ face_selector_age_start = state_manager.get_item('face_selector_age_start') or facefusion.choices.face_selector_age_range[0]
79
+ face_selector_age_end = state_manager.get_item('face_selector_age_end') or facefusion.choices.face_selector_age_range[-1]
80
+ FACE_SELECTOR_AGE_RANGE_SLIDER = RangeSlider(
81
+ label = translator.get('uis.face_selector_age_range_slider'),
82
+ minimum = facefusion.choices.face_selector_age_range[0],
83
+ maximum = facefusion.choices.face_selector_age_range[-1],
84
+ value = (face_selector_age_start, face_selector_age_end),
85
+ step = calculate_int_step(facefusion.choices.face_selector_age_range)
86
+ )
87
+ REFERENCE_FACE_DISTANCE_SLIDER = gradio.Slider(
88
+ label = translator.get('uis.reference_face_distance_slider'),
89
+ value = state_manager.get_item('reference_face_distance'),
90
+ step = calculate_float_step(facefusion.choices.reference_face_distance_range),
91
+ minimum = facefusion.choices.reference_face_distance_range[0],
92
+ maximum = facefusion.choices.reference_face_distance_range[-1],
93
+ visible = 'reference' in state_manager.get_item('face_selector_mode')
94
+ )
95
+ register_ui_component('face_selector_mode_dropdown', FACE_SELECTOR_MODE_DROPDOWN)
96
+ register_ui_component('face_selector_order_dropdown', FACE_SELECTOR_ORDER_DROPDOWN)
97
+ register_ui_component('face_selector_gender_dropdown', FACE_SELECTOR_GENDER_DROPDOWN)
98
+ register_ui_component('face_selector_race_dropdown', FACE_SELECTOR_RACE_DROPDOWN)
99
+ register_ui_component('face_selector_age_range_slider', FACE_SELECTOR_AGE_RANGE_SLIDER)
100
+ register_ui_component('reference_face_position_gallery', REFERENCE_FACE_POSITION_GALLERY)
101
+ register_ui_component('reference_face_distance_slider', REFERENCE_FACE_DISTANCE_SLIDER)
102
+
103
+
104
+ def listen() -> None:
105
+ FACE_SELECTOR_MODE_DROPDOWN.change(update_face_selector_mode, inputs = FACE_SELECTOR_MODE_DROPDOWN, outputs = [ REFERENCE_FACE_POSITION_GALLERY, REFERENCE_FACE_DISTANCE_SLIDER ])
106
+ FACE_SELECTOR_ORDER_DROPDOWN.change(update_face_selector_order, inputs = FACE_SELECTOR_ORDER_DROPDOWN, outputs = REFERENCE_FACE_POSITION_GALLERY)
107
+ FACE_SELECTOR_GENDER_DROPDOWN.change(update_face_selector_gender, inputs = FACE_SELECTOR_GENDER_DROPDOWN, outputs = REFERENCE_FACE_POSITION_GALLERY)
108
+ FACE_SELECTOR_RACE_DROPDOWN.change(update_face_selector_race, inputs = FACE_SELECTOR_RACE_DROPDOWN, outputs = REFERENCE_FACE_POSITION_GALLERY)
109
+ FACE_SELECTOR_AGE_RANGE_SLIDER.release(update_face_selector_age_range, inputs = FACE_SELECTOR_AGE_RANGE_SLIDER, outputs = REFERENCE_FACE_POSITION_GALLERY)
110
+ REFERENCE_FACE_DISTANCE_SLIDER.release(update_reference_face_distance, inputs = REFERENCE_FACE_DISTANCE_SLIDER)
111
+
112
+ preview_frame_slider = get_ui_component('preview_frame_slider')
113
+ if preview_frame_slider:
114
+ REFERENCE_FACE_POSITION_GALLERY.select(update_reference_frame_number, inputs = preview_frame_slider)
115
+ REFERENCE_FACE_POSITION_GALLERY.select(update_reference_face_position)
116
+
117
+ for ui_component in get_ui_components(
118
+ [
119
+ 'target_image',
120
+ 'target_video'
121
+ ]):
122
+ for method in [ 'change', 'clear' ]:
123
+ getattr(ui_component, method)(clear_reference_frame_number)
124
+ getattr(ui_component, method)(clear_reference_face_position)
125
+ getattr(ui_component, method)(update_reference_position_gallery, outputs = REFERENCE_FACE_POSITION_GALLERY)
126
+
127
+ for ui_component in get_ui_components(
128
+ [
129
+ 'face_detector_model_dropdown',
130
+ 'face_detector_size_dropdown',
131
+ 'face_detector_angles_checkbox_group'
132
+ ]):
133
+ ui_component.change(clear_and_update_reference_position_gallery, outputs = REFERENCE_FACE_POSITION_GALLERY)
134
+
135
+ face_detector_score_slider = get_ui_component('face_detector_score_slider')
136
+ if face_detector_score_slider:
137
+ face_detector_score_slider.release(update_reference_position_gallery, outputs = REFERENCE_FACE_POSITION_GALLERY)
138
+
139
+ preview_frame_slider = get_ui_component('preview_frame_slider')
140
+ if preview_frame_slider:
141
+ for method in [ 'change', 'release' ]:
142
+ getattr(preview_frame_slider, method)(update_reference_position_gallery, inputs = preview_frame_slider, outputs = REFERENCE_FACE_POSITION_GALLERY, show_progress = 'hidden')
143
+
144
+
145
+ def update_face_selector_mode(face_selector_mode : FaceSelectorMode) -> Tuple[gradio.Gallery, gradio.Slider]:
146
+ state_manager.set_item('face_selector_mode', face_selector_mode)
147
+ if face_selector_mode == 'many':
148
+ return gradio.Gallery(visible = False), gradio.Slider(visible = False)
149
+ if face_selector_mode == 'one':
150
+ return gradio.Gallery(visible = False), gradio.Slider(visible = False)
151
+ if face_selector_mode == 'reference':
152
+ return gradio.Gallery(visible = True), gradio.Slider(visible = True)
153
+
154
+
155
+ def update_face_selector_order(face_analyser_order : FaceSelectorOrder) -> gradio.Gallery:
156
+ state_manager.set_item('face_selector_order', convert_str_none(face_analyser_order))
157
+ return update_reference_position_gallery()
158
+
159
+
160
+ def update_face_selector_gender(face_selector_gender : FaceSelectorGender) -> gradio.Gallery:
161
+ state_manager.set_item('face_selector_gender', convert_str_none(face_selector_gender))
162
+ return update_reference_position_gallery()
163
+
164
+
165
+ def update_face_selector_race(face_selector_race : FaceSelectorRace) -> gradio.Gallery:
166
+ state_manager.set_item('face_selector_race', convert_str_none(face_selector_race))
167
+ return update_reference_position_gallery()
168
+
169
+
170
+ def update_face_selector_age_range(face_selector_age_range : Tuple[float, float]) -> gradio.Gallery:
171
+ face_selector_age_start, face_selector_age_end = face_selector_age_range
172
+ state_manager.set_item('face_selector_age_start', int(face_selector_age_start))
173
+ state_manager.set_item('face_selector_age_end', int(face_selector_age_end))
174
+ return update_reference_position_gallery()
175
+
176
+
177
+ def update_reference_face_position(event : gradio.SelectData) -> None:
178
+ state_manager.set_item('reference_face_position', event.index)
179
+
180
+
181
+ def clear_reference_face_position() -> None:
182
+ state_manager.set_item('reference_face_position', 0)
183
+
184
+
185
+ def update_reference_face_distance(reference_face_distance : float) -> None:
186
+ state_manager.set_item('reference_face_distance', reference_face_distance)
187
+
188
+
189
+ def update_reference_frame_number(reference_frame_number : int = 0) -> None:
190
+ state_manager.set_item('reference_frame_number', reference_frame_number)
191
+
192
+
193
+ def clear_reference_frame_number() -> None:
194
+ state_manager.set_item('reference_frame_number', 0)
195
+
196
+
197
+ def clear_and_update_reference_position_gallery() -> gradio.Gallery:
198
+ clear_faces()
199
+ return update_reference_position_gallery()
200
+
201
+
202
+ def update_reference_position_gallery(frame_number : int = 0) -> gradio.Gallery:
203
+ gallery_vision_frames = []
204
+ source_vision_frames = read_static_images(filter_image_paths(state_manager.get_item('source_paths')))
205
+
206
+ if is_image(state_manager.get_item('target_path')):
207
+ target_vision_frame = read_static_image(state_manager.get_item('target_path'))
208
+ gallery_vision_frames = extract_gallery_frames(source_vision_frames, target_vision_frame)
209
+ if is_video(state_manager.get_item('target_path')):
210
+ target_vision_frame = read_video_frame(state_manager.get_item('target_path'), frame_number)
211
+ gallery_vision_frames = extract_gallery_frames(source_vision_frames, target_vision_frame)
212
+ if gallery_vision_frames:
213
+ return gradio.Gallery(value = gallery_vision_frames)
214
+ return gradio.Gallery(value = None)
215
+
216
+
217
+ def extract_gallery_frames(source_vision_frames : List[VisionFrame], target_vision_frame : VisionFrame) -> List[VisionFrame]:
218
+ gallery_vision_frames = []
219
+ source_faces = get_many_faces(source_vision_frames)
220
+ target_faces = get_many_faces([ target_vision_frame ])
221
+ target_faces = sort_and_filter_faces(source_faces, target_faces)
222
+
223
+ for target_face in target_faces:
224
+ start_x, start_y, end_x, end_y = map(int, target_face.bounding_box)
225
+ padding_x = int((end_x - start_x) * 0.25)
226
+ padding_y = int((end_y - start_y) * 0.25)
227
+ start_x = max(0, start_x - padding_x)
228
+ start_y = max(0, start_y - padding_y)
229
+ end_x = max(0, end_x + padding_x)
230
+ end_y = max(0, end_y + padding_y)
231
+ crop_vision_frame = target_vision_frame[start_y:end_y, start_x:end_x]
232
+ crop_vision_frame = fit_cover_frame(crop_vision_frame, (128, 128))
233
+ crop_vision_frame = cv2.cvtColor(crop_vision_frame, cv2.COLOR_BGR2RGB)
234
+ gallery_vision_frames.append(crop_vision_frame)
235
+
236
+ return gallery_vision_frames
uis/components/face_swapper_options.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.common_helper import calculate_float_step, get_first
7
+ from facefusion.processors.core import load_processor_module
8
+ from facefusion.processors.modules.face_swapper import choices as face_swapper_choices
9
+ from facefusion.processors.modules.face_swapper.types import FaceSwapperModel, FaceSwapperWeight
10
+ from facefusion.uis.core import get_ui_component, register_ui_component
11
+
12
+ FACE_SWAPPER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
13
+ FACE_SWAPPER_PIXEL_BOOST_DROPDOWN : Optional[gradio.Dropdown] = None
14
+ FACE_SWAPPER_WEIGHT_SLIDER : Optional[gradio.Slider] = None
15
+
16
+
17
+ def render() -> None:
18
+ global FACE_SWAPPER_MODEL_DROPDOWN
19
+ global FACE_SWAPPER_PIXEL_BOOST_DROPDOWN
20
+ global FACE_SWAPPER_WEIGHT_SLIDER
21
+
22
+ has_face_swapper = 'face_swapper' in state_manager.get_item('processors')
23
+ FACE_SWAPPER_MODEL_DROPDOWN = gradio.Dropdown(
24
+ label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.face_swapper'),
25
+ choices = face_swapper_choices.face_swapper_models,
26
+ value = state_manager.get_item('face_swapper_model'),
27
+ visible = has_face_swapper
28
+ )
29
+ FACE_SWAPPER_PIXEL_BOOST_DROPDOWN = gradio.Dropdown(
30
+ label = translator.get('uis.pixel_boost_dropdown', 'facefusion.processors.modules.face_swapper'),
31
+ choices = face_swapper_choices.face_swapper_set.get(state_manager.get_item('face_swapper_model')),
32
+ value = state_manager.get_item('face_swapper_pixel_boost'),
33
+ visible = has_face_swapper
34
+ )
35
+ FACE_SWAPPER_WEIGHT_SLIDER = gradio.Slider(
36
+ label = translator.get('uis.weight_slider', 'facefusion.processors.modules.face_swapper'),
37
+ value = state_manager.get_item('face_swapper_weight'),
38
+ minimum = face_swapper_choices.face_swapper_weight_range[0],
39
+ maximum = face_swapper_choices.face_swapper_weight_range[-1],
40
+ step = calculate_float_step(face_swapper_choices.face_swapper_weight_range),
41
+ visible = has_face_swapper and has_face_swapper_weight()
42
+ )
43
+ register_ui_component('face_swapper_model_dropdown', FACE_SWAPPER_MODEL_DROPDOWN)
44
+ register_ui_component('face_swapper_pixel_boost_dropdown', FACE_SWAPPER_PIXEL_BOOST_DROPDOWN)
45
+ register_ui_component('face_swapper_weight_slider', FACE_SWAPPER_WEIGHT_SLIDER)
46
+
47
+
48
+ def listen() -> None:
49
+ FACE_SWAPPER_MODEL_DROPDOWN.change(update_face_swapper_model, inputs = FACE_SWAPPER_MODEL_DROPDOWN, outputs = [ FACE_SWAPPER_MODEL_DROPDOWN, FACE_SWAPPER_PIXEL_BOOST_DROPDOWN, FACE_SWAPPER_WEIGHT_SLIDER ])
50
+ FACE_SWAPPER_PIXEL_BOOST_DROPDOWN.change(update_face_swapper_pixel_boost, inputs = FACE_SWAPPER_PIXEL_BOOST_DROPDOWN)
51
+ FACE_SWAPPER_WEIGHT_SLIDER.change(update_face_swapper_weight, inputs = FACE_SWAPPER_WEIGHT_SLIDER)
52
+
53
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
54
+ if processors_checkbox_group:
55
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ FACE_SWAPPER_MODEL_DROPDOWN, FACE_SWAPPER_PIXEL_BOOST_DROPDOWN, FACE_SWAPPER_WEIGHT_SLIDER ])
56
+
57
+
58
+ def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Dropdown, gradio.Slider]:
59
+ has_face_swapper = 'face_swapper' in processors
60
+ return gradio.Dropdown(visible = has_face_swapper), gradio.Dropdown(visible = has_face_swapper), gradio.Slider(visible = has_face_swapper)
61
+
62
+
63
+ def update_face_swapper_model(face_swapper_model : FaceSwapperModel) -> Tuple[gradio.Dropdown, gradio.Dropdown, gradio.Slider]:
64
+ face_swapper_module = load_processor_module('face_swapper')
65
+ face_swapper_module.clear_inference_pool()
66
+ state_manager.set_item('face_swapper_model', face_swapper_model)
67
+
68
+ if face_swapper_module.pre_check():
69
+ face_swapper_pixel_boost_dropdown_choices = face_swapper_choices.face_swapper_set.get(state_manager.get_item('face_swapper_model'))
70
+ state_manager.set_item('face_swapper_pixel_boost', get_first(face_swapper_pixel_boost_dropdown_choices))
71
+ return gradio.Dropdown(value = state_manager.get_item('face_swapper_model')), gradio.Dropdown(value = state_manager.get_item('face_swapper_pixel_boost'), choices = face_swapper_pixel_boost_dropdown_choices), gradio.Slider(visible = has_face_swapper_weight())
72
+ return gradio.Dropdown(), gradio.Dropdown(), gradio.Slider()
73
+
74
+
75
+ def update_face_swapper_pixel_boost(face_swapper_pixel_boost : str) -> None:
76
+ state_manager.set_item('face_swapper_pixel_boost', face_swapper_pixel_boost)
77
+
78
+
79
+ def update_face_swapper_weight(face_swapper_weight : FaceSwapperWeight) -> None:
80
+ state_manager.set_item('face_swapper_weight', face_swapper_weight)
81
+
82
+
83
+ def has_face_swapper_weight() -> bool:
84
+ return state_manager.get_item('face_swapper_model') in [ 'ghost_1_256', 'ghost_2_256', 'ghost_3_256', 'hififace_unofficial_256', 'hyperswap_1a_256', 'hyperswap_1b_256', 'hyperswap_1c_256', 'inswapper_128', 'inswapper_128_fp16', 'simswap_256', 'simswap_unofficial_512' ]
uis/components/face_tracker.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import state_manager, translator
7
+ from facefusion.common_helper import calculate_float_step
8
+ from facefusion.types import Score
9
+ from facefusion.uis.core import register_ui_component
10
+
11
+ FACE_TRACKER_SCORE_SLIDER : Optional[gradio.Slider] = None
12
+
13
+
14
+ def render() -> None:
15
+ global FACE_TRACKER_SCORE_SLIDER
16
+
17
+ FACE_TRACKER_SCORE_SLIDER = gradio.Slider(
18
+ label = translator.get('uis.face_tracker_score_slider'),
19
+ value = state_manager.get_item('face_tracker_score'),
20
+ step = calculate_float_step(facefusion.choices.face_tracker_score_range),
21
+ minimum = facefusion.choices.face_tracker_score_range[0],
22
+ maximum = facefusion.choices.face_tracker_score_range[-1]
23
+ )
24
+ register_ui_component('face_tracker_score_slider', FACE_TRACKER_SCORE_SLIDER)
25
+
26
+
27
+ def listen() -> None:
28
+ FACE_TRACKER_SCORE_SLIDER.release(update_face_tracker_score, inputs = FACE_TRACKER_SCORE_SLIDER)
29
+
30
+
31
+ def update_face_tracker_score(face_tracker_score : Score) -> None:
32
+ state_manager.set_item('face_tracker_score', face_tracker_score)
uis/components/frame_colorizer_options.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.common_helper import calculate_int_step
7
+ from facefusion.processors.core import load_processor_module
8
+ from facefusion.processors.modules.frame_colorizer import choices as frame_colorizer_choices
9
+ from facefusion.processors.modules.frame_colorizer.types import FrameColorizerModel
10
+ from facefusion.uis.core import get_ui_component, register_ui_component
11
+
12
+ FRAME_COLORIZER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
13
+ FRAME_COLORIZER_SIZE_DROPDOWN : Optional[gradio.Dropdown] = None
14
+ FRAME_COLORIZER_BLEND_SLIDER : Optional[gradio.Slider] = None
15
+
16
+
17
+ def render() -> None:
18
+ global FRAME_COLORIZER_MODEL_DROPDOWN
19
+ global FRAME_COLORIZER_SIZE_DROPDOWN
20
+ global FRAME_COLORIZER_BLEND_SLIDER
21
+
22
+ has_frame_colorizer = 'frame_colorizer' in state_manager.get_item('processors')
23
+ FRAME_COLORIZER_MODEL_DROPDOWN = gradio.Dropdown(
24
+ label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.frame_colorizer'),
25
+ choices = frame_colorizer_choices.frame_colorizer_models,
26
+ value = state_manager.get_item('frame_colorizer_model'),
27
+ visible = has_frame_colorizer
28
+ )
29
+ FRAME_COLORIZER_SIZE_DROPDOWN = gradio.Dropdown(
30
+ label = translator.get('uis.size_dropdown', 'facefusion.processors.modules.frame_colorizer'),
31
+ choices = frame_colorizer_choices.frame_colorizer_sizes,
32
+ value = state_manager.get_item('frame_colorizer_size'),
33
+ visible = has_frame_colorizer
34
+ )
35
+ FRAME_COLORIZER_BLEND_SLIDER = gradio.Slider(
36
+ label = translator.get('uis.blend_slider', 'facefusion.processors.modules.frame_colorizer'),
37
+ value = state_manager.get_item('frame_colorizer_blend'),
38
+ step = calculate_int_step(frame_colorizer_choices.frame_colorizer_blend_range),
39
+ minimum = frame_colorizer_choices.frame_colorizer_blend_range[0],
40
+ maximum = frame_colorizer_choices.frame_colorizer_blend_range[-1],
41
+ visible = has_frame_colorizer
42
+ )
43
+ register_ui_component('frame_colorizer_model_dropdown', FRAME_COLORIZER_MODEL_DROPDOWN)
44
+ register_ui_component('frame_colorizer_size_dropdown', FRAME_COLORIZER_SIZE_DROPDOWN)
45
+ register_ui_component('frame_colorizer_blend_slider', FRAME_COLORIZER_BLEND_SLIDER)
46
+
47
+
48
+ def listen() -> None:
49
+ FRAME_COLORIZER_MODEL_DROPDOWN.change(update_frame_colorizer_model, inputs = FRAME_COLORIZER_MODEL_DROPDOWN, outputs = FRAME_COLORIZER_MODEL_DROPDOWN)
50
+ FRAME_COLORIZER_SIZE_DROPDOWN.change(update_frame_colorizer_size, inputs = FRAME_COLORIZER_SIZE_DROPDOWN)
51
+ FRAME_COLORIZER_BLEND_SLIDER.release(update_frame_colorizer_blend, inputs = FRAME_COLORIZER_BLEND_SLIDER)
52
+
53
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
54
+ if processors_checkbox_group:
55
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ FRAME_COLORIZER_MODEL_DROPDOWN, FRAME_COLORIZER_BLEND_SLIDER, FRAME_COLORIZER_SIZE_DROPDOWN ])
56
+
57
+
58
+ def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider, gradio.Dropdown]:
59
+ has_frame_colorizer = 'frame_colorizer' in processors
60
+ return gradio.Dropdown(visible = has_frame_colorizer), gradio.Slider(visible = has_frame_colorizer), gradio.Dropdown(visible = has_frame_colorizer)
61
+
62
+
63
+ def update_frame_colorizer_model(frame_colorizer_model : FrameColorizerModel) -> gradio.Dropdown:
64
+ frame_colorizer_module = load_processor_module('frame_colorizer')
65
+ frame_colorizer_module.clear_inference_pool()
66
+ state_manager.set_item('frame_colorizer_model', frame_colorizer_model)
67
+
68
+ if frame_colorizer_module.pre_check():
69
+ return gradio.Dropdown(value = state_manager.get_item('frame_colorizer_model'))
70
+ return gradio.Dropdown()
71
+
72
+
73
+ def update_frame_colorizer_size(frame_colorizer_size : str) -> None:
74
+ state_manager.set_item('frame_colorizer_size', frame_colorizer_size)
75
+
76
+
77
+ def update_frame_colorizer_blend(frame_colorizer_blend : float) -> None:
78
+ state_manager.set_item('frame_colorizer_blend', int(frame_colorizer_blend))
79
+
80
+
81
+
uis/components/frame_enhancer_options.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.common_helper import calculate_int_step
7
+ from facefusion.processors.core import load_processor_module
8
+ from facefusion.processors.modules.frame_enhancer import choices as frame_enhancer_choices
9
+ from facefusion.processors.modules.frame_enhancer.types import FrameEnhancerModel
10
+ from facefusion.uis.core import get_ui_component, register_ui_component
11
+
12
+ FRAME_ENHANCER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
13
+ FRAME_ENHANCER_BLEND_SLIDER : Optional[gradio.Slider] = None
14
+
15
+
16
+ def render() -> None:
17
+ global FRAME_ENHANCER_MODEL_DROPDOWN
18
+ global FRAME_ENHANCER_BLEND_SLIDER
19
+
20
+ has_frame_enhancer = 'frame_enhancer' in state_manager.get_item('processors')
21
+ FRAME_ENHANCER_MODEL_DROPDOWN = gradio.Dropdown(
22
+ label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.frame_enhancer'),
23
+ choices = frame_enhancer_choices.frame_enhancer_models,
24
+ value = state_manager.get_item('frame_enhancer_model'),
25
+ visible = has_frame_enhancer
26
+ )
27
+ FRAME_ENHANCER_BLEND_SLIDER = gradio.Slider(
28
+ label = translator.get('uis.blend_slider', 'facefusion.processors.modules.frame_enhancer'),
29
+ value = state_manager.get_item('frame_enhancer_blend'),
30
+ step = calculate_int_step(frame_enhancer_choices.frame_enhancer_blend_range),
31
+ minimum = frame_enhancer_choices.frame_enhancer_blend_range[0],
32
+ maximum = frame_enhancer_choices.frame_enhancer_blend_range[-1],
33
+ visible = has_frame_enhancer
34
+ )
35
+ register_ui_component('frame_enhancer_model_dropdown', FRAME_ENHANCER_MODEL_DROPDOWN)
36
+ register_ui_component('frame_enhancer_blend_slider', FRAME_ENHANCER_BLEND_SLIDER)
37
+
38
+
39
+ def listen() -> None:
40
+ FRAME_ENHANCER_MODEL_DROPDOWN.change(update_frame_enhancer_model, inputs = FRAME_ENHANCER_MODEL_DROPDOWN, outputs = FRAME_ENHANCER_MODEL_DROPDOWN)
41
+ FRAME_ENHANCER_BLEND_SLIDER.release(update_frame_enhancer_blend, inputs = FRAME_ENHANCER_BLEND_SLIDER)
42
+
43
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
44
+ if processors_checkbox_group:
45
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ FRAME_ENHANCER_MODEL_DROPDOWN, FRAME_ENHANCER_BLEND_SLIDER ])
46
+
47
+
48
+ def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider]:
49
+ has_frame_enhancer = 'frame_enhancer' in processors
50
+ return gradio.Dropdown(visible = has_frame_enhancer), gradio.Slider(visible = has_frame_enhancer)
51
+
52
+
53
+ def update_frame_enhancer_model(frame_enhancer_model : FrameEnhancerModel) -> gradio.Dropdown:
54
+ frame_enhancer_module = load_processor_module('frame_enhancer')
55
+ frame_enhancer_module.clear_inference_pool()
56
+ state_manager.set_item('frame_enhancer_model', frame_enhancer_model)
57
+
58
+ if frame_enhancer_module.pre_check():
59
+ return gradio.Dropdown(value = state_manager.get_item('frame_enhancer_model'))
60
+ return gradio.Dropdown()
61
+
62
+
63
+ def update_frame_enhancer_blend(frame_enhancer_blend : float) -> None:
64
+ state_manager.set_item('frame_enhancer_blend', int(frame_enhancer_blend))
uis/components/instant_runner.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from time import sleep
2
+ from typing import Optional, Tuple
3
+
4
+ import gradio
5
+
6
+ from facefusion import process_manager, state_manager, translator
7
+ from facefusion.args import collect_step_args
8
+ from facefusion.core import process_step
9
+ from facefusion.filesystem import is_directory, is_image, is_video
10
+ from facefusion.jobs import job_helper, job_manager, job_runner, job_store
11
+ from facefusion.temp_helper import clear_temp_directory
12
+ from facefusion.types import Args, UiWorkflow
13
+ from facefusion.uis.core import get_ui_component
14
+ from facefusion.uis.ui_helper import suggest_output_path
15
+
16
+ INSTANT_RUNNER_WRAPPER : Optional[gradio.Row] = None
17
+ INSTANT_RUNNER_START_BUTTON : Optional[gradio.Button] = None
18
+ INSTANT_RUNNER_STOP_BUTTON : Optional[gradio.Button] = None
19
+ INSTANT_RUNNER_CLEAR_BUTTON : Optional[gradio.Button] = None
20
+
21
+
22
+ def render() -> None:
23
+ global INSTANT_RUNNER_WRAPPER
24
+ global INSTANT_RUNNER_START_BUTTON
25
+ global INSTANT_RUNNER_STOP_BUTTON
26
+ global INSTANT_RUNNER_CLEAR_BUTTON
27
+
28
+ if job_manager.init_jobs(state_manager.get_item('jobs_path')):
29
+ is_instant_runner = state_manager.get_item('ui_workflow') == 'instant_runner'
30
+
31
+ with gradio.Row(visible = is_instant_runner) as INSTANT_RUNNER_WRAPPER:
32
+ INSTANT_RUNNER_START_BUTTON = gradio.Button(
33
+ value = translator.get('uis.start_button'),
34
+ variant = 'primary',
35
+ size = 'sm'
36
+ )
37
+ INSTANT_RUNNER_STOP_BUTTON = gradio.Button(
38
+ value = translator.get('uis.stop_button'),
39
+ variant = 'primary',
40
+ size = 'sm',
41
+ visible = False
42
+ )
43
+ INSTANT_RUNNER_CLEAR_BUTTON = gradio.Button(
44
+ value = translator.get('uis.clear_button'),
45
+ size = 'sm'
46
+ )
47
+
48
+
49
+ def listen() -> None:
50
+ output_image = get_ui_component('output_image')
51
+ output_video = get_ui_component('output_video')
52
+ ui_workflow_dropdown = get_ui_component('ui_workflow_dropdown')
53
+
54
+ if output_image and output_video:
55
+ INSTANT_RUNNER_START_BUTTON.click(start, outputs = [ INSTANT_RUNNER_START_BUTTON, INSTANT_RUNNER_STOP_BUTTON ])
56
+ INSTANT_RUNNER_START_BUTTON.click(run, outputs = [ INSTANT_RUNNER_START_BUTTON, INSTANT_RUNNER_STOP_BUTTON, output_image, output_video ])
57
+ INSTANT_RUNNER_STOP_BUTTON.click(stop, outputs = [ INSTANT_RUNNER_START_BUTTON, INSTANT_RUNNER_STOP_BUTTON, output_image, output_video ])
58
+ INSTANT_RUNNER_CLEAR_BUTTON.click(clear, outputs = [ output_image, output_video ])
59
+ if ui_workflow_dropdown:
60
+ ui_workflow_dropdown.change(remote_update, inputs = ui_workflow_dropdown, outputs = INSTANT_RUNNER_WRAPPER)
61
+
62
+
63
+ def remote_update(ui_workflow : UiWorkflow) -> gradio.Row:
64
+ is_instant_runner = ui_workflow == 'instant_runner'
65
+
66
+ return gradio.Row(visible = is_instant_runner)
67
+
68
+
69
+ def start() -> Tuple[gradio.Button, gradio.Button]:
70
+ while not process_manager.is_processing():
71
+ sleep(0.5)
72
+ return gradio.Button(visible = False), gradio.Button(visible = True)
73
+
74
+
75
+ def run() -> Tuple[gradio.Button, gradio.Button, gradio.Image, gradio.Video]:
76
+ step_args = collect_step_args()
77
+ output_path = step_args.get('output_path')
78
+
79
+ if is_directory(step_args.get('output_path')):
80
+ step_args['output_path'] = suggest_output_path(step_args.get('output_path'), state_manager.get_item('target_path'))
81
+ if job_manager.init_jobs(state_manager.get_item('jobs_path')):
82
+ create_and_run_job(step_args)
83
+ state_manager.set_item('output_path', output_path)
84
+ if is_image(step_args.get('output_path')):
85
+ return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Image(value = step_args.get('output_path'), visible = True), gradio.Video(value = None, visible = False)
86
+ if is_video(step_args.get('output_path')):
87
+ return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Image(value = None, visible = False), gradio.Video(value = step_args.get('output_path'), visible = True)
88
+ return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Image(value = None), gradio.Video(value = None)
89
+
90
+
91
+ def create_and_run_job(step_args : Args) -> bool:
92
+ job_id = job_helper.suggest_job_id('ui')
93
+
94
+ for key in job_store.get_job_keys():
95
+ state_manager.sync_item(key) #type:ignore[arg-type]
96
+
97
+ return job_manager.create_job(job_id) and job_manager.add_step(job_id, step_args) and job_manager.submit_job(job_id) and job_runner.run_job(job_id, process_step)
98
+
99
+
100
+ def stop() -> Tuple[gradio.Button, gradio.Button, gradio.Image, gradio.Video]:
101
+ process_manager.stop()
102
+ return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Image(value = None), gradio.Video(value = None)
103
+
104
+
105
+ def clear() -> Tuple[gradio.Image, gradio.Video]:
106
+ while process_manager.is_processing():
107
+ sleep(0.5)
108
+ if state_manager.get_item('target_path'):
109
+ clear_temp_directory(state_manager.get_item('target_path'))
110
+ return gradio.Image(value = None), gradio.Video(value = None)
uis/components/job_list.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import state_manager, translator
7
+ from facefusion.common_helper import get_first
8
+ from facefusion.jobs import job_list, job_manager
9
+ from facefusion.types import JobStatus
10
+ from facefusion.uis.core import get_ui_component
11
+
12
+ JOB_LIST_JOBS_DATAFRAME : Optional[gradio.Dataframe] = None
13
+ JOB_LIST_REFRESH_BUTTON : Optional[gradio.Button] = None
14
+
15
+
16
+ def render() -> None:
17
+ global JOB_LIST_JOBS_DATAFRAME
18
+ global JOB_LIST_REFRESH_BUTTON
19
+
20
+ if job_manager.init_jobs(state_manager.get_item('jobs_path')):
21
+ job_status = get_first(facefusion.choices.job_statuses)
22
+ job_headers, job_contents = job_list.compose_job_list(job_status)
23
+
24
+ JOB_LIST_JOBS_DATAFRAME = gradio.Dataframe(
25
+ headers = job_headers,
26
+ value = job_contents,
27
+ datatype = [ 'str', 'number', 'date', 'date', 'str' ],
28
+ show_label = False
29
+ )
30
+ JOB_LIST_REFRESH_BUTTON = gradio.Button(
31
+ value = translator.get('uis.refresh_button'),
32
+ variant = 'primary',
33
+ size = 'sm'
34
+ )
35
+
36
+
37
+ def listen() -> None:
38
+ job_list_job_status_checkbox_group = get_ui_component('job_list_job_status_checkbox_group')
39
+ if job_list_job_status_checkbox_group:
40
+ job_list_job_status_checkbox_group.change(update_job_dataframe, inputs = job_list_job_status_checkbox_group, outputs = JOB_LIST_JOBS_DATAFRAME)
41
+ JOB_LIST_REFRESH_BUTTON.click(update_job_dataframe, inputs = job_list_job_status_checkbox_group, outputs = JOB_LIST_JOBS_DATAFRAME)
42
+
43
+
44
+ def update_job_dataframe(job_statuses : List[JobStatus]) -> gradio.Dataframe:
45
+ all_job_contents = []
46
+
47
+ for job_status in job_statuses:
48
+ _, job_contents = job_list.compose_job_list(job_status)
49
+ all_job_contents.extend(job_contents)
50
+ return gradio.Dataframe(value = all_job_contents)
uis/components/job_list_options.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import state_manager, translator
7
+ from facefusion.common_helper import get_first
8
+ from facefusion.jobs import job_manager
9
+ from facefusion.types import JobStatus
10
+ from facefusion.uis.core import register_ui_component
11
+
12
+ JOB_LIST_JOB_STATUS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
13
+
14
+
15
+ def render() -> None:
16
+ global JOB_LIST_JOB_STATUS_CHECKBOX_GROUP
17
+
18
+ if job_manager.init_jobs(state_manager.get_item('jobs_path')):
19
+ job_status = get_first(facefusion.choices.job_statuses)
20
+
21
+ JOB_LIST_JOB_STATUS_CHECKBOX_GROUP = gradio.CheckboxGroup(
22
+ label = translator.get('uis.job_list_status_checkbox_group'),
23
+ choices = facefusion.choices.job_statuses,
24
+ value = job_status
25
+ )
26
+ register_ui_component('job_list_job_status_checkbox_group', JOB_LIST_JOB_STATUS_CHECKBOX_GROUP)
27
+
28
+
29
+ def listen() -> None:
30
+ JOB_LIST_JOB_STATUS_CHECKBOX_GROUP.change(update_job_status_checkbox_group, inputs = JOB_LIST_JOB_STATUS_CHECKBOX_GROUP, outputs = JOB_LIST_JOB_STATUS_CHECKBOX_GROUP)
31
+
32
+
33
+ def update_job_status_checkbox_group(job_statuses : List[JobStatus]) -> gradio.CheckboxGroup:
34
+ job_statuses = job_statuses or facefusion.choices.job_statuses
35
+ return gradio.CheckboxGroup(value = job_statuses)
uis/components/job_manager.py ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import logger, state_manager, translator
6
+ from facefusion.args import collect_step_args
7
+ from facefusion.common_helper import get_first, get_last
8
+ from facefusion.filesystem import is_directory
9
+ from facefusion.jobs import job_manager
10
+ from facefusion.types import UiWorkflow
11
+ from facefusion.uis import choices as uis_choices
12
+ from facefusion.uis.core import get_ui_component
13
+ from facefusion.uis.types import JobManagerAction
14
+ from facefusion.uis.ui_helper import convert_int_none, convert_str_none, suggest_output_path
15
+
16
+ JOB_MANAGER_WRAPPER : Optional[gradio.Column] = None
17
+ JOB_MANAGER_JOB_ACTION_DROPDOWN : Optional[gradio.Dropdown] = None
18
+ JOB_MANAGER_JOB_ID_TEXTBOX : Optional[gradio.Textbox] = None
19
+ JOB_MANAGER_JOB_ID_DROPDOWN : Optional[gradio.Dropdown] = None
20
+ JOB_MANAGER_STEP_INDEX_DROPDOWN : Optional[gradio.Dropdown] = None
21
+ JOB_MANAGER_APPLY_BUTTON : Optional[gradio.Button] = None
22
+
23
+
24
+ def render() -> None:
25
+ global JOB_MANAGER_WRAPPER
26
+ global JOB_MANAGER_JOB_ACTION_DROPDOWN
27
+ global JOB_MANAGER_JOB_ID_TEXTBOX
28
+ global JOB_MANAGER_JOB_ID_DROPDOWN
29
+ global JOB_MANAGER_STEP_INDEX_DROPDOWN
30
+ global JOB_MANAGER_APPLY_BUTTON
31
+
32
+ if job_manager.init_jobs(state_manager.get_item('jobs_path')):
33
+ is_job_manager = state_manager.get_item('ui_workflow') == 'job_manager'
34
+ drafted_job_ids = job_manager.find_job_ids('drafted') or [ 'none' ]
35
+
36
+ with gradio.Column(visible = is_job_manager) as JOB_MANAGER_WRAPPER:
37
+ JOB_MANAGER_JOB_ACTION_DROPDOWN = gradio.Dropdown(
38
+ label = translator.get('uis.job_manager_job_action_dropdown'),
39
+ choices = uis_choices.job_manager_actions,
40
+ value = get_first(uis_choices.job_manager_actions)
41
+ )
42
+ JOB_MANAGER_JOB_ID_TEXTBOX = gradio.Textbox(
43
+ label = translator.get('uis.job_manager_job_id_dropdown'),
44
+ max_lines = 1,
45
+ interactive = True
46
+ )
47
+ JOB_MANAGER_JOB_ID_DROPDOWN = gradio.Dropdown(
48
+ label = translator.get('uis.job_manager_job_id_dropdown'),
49
+ choices = drafted_job_ids,
50
+ value = get_last(drafted_job_ids),
51
+ interactive = True,
52
+ visible = False
53
+ )
54
+ JOB_MANAGER_STEP_INDEX_DROPDOWN = gradio.Dropdown(
55
+ label = translator.get('uis.job_manager_step_index_dropdown'),
56
+ choices = [ 'none' ],
57
+ value = 'none',
58
+ interactive = True,
59
+ visible = False
60
+ )
61
+ JOB_MANAGER_APPLY_BUTTON = gradio.Button(
62
+ value = translator.get('uis.apply_button'),
63
+ variant = 'primary',
64
+ size = 'sm'
65
+ )
66
+
67
+
68
+ def listen() -> None:
69
+ JOB_MANAGER_JOB_ACTION_DROPDOWN.change(update, inputs = [ JOB_MANAGER_JOB_ACTION_DROPDOWN, JOB_MANAGER_JOB_ID_DROPDOWN ], outputs = [ JOB_MANAGER_JOB_ID_TEXTBOX, JOB_MANAGER_JOB_ID_DROPDOWN, JOB_MANAGER_STEP_INDEX_DROPDOWN ])
70
+ JOB_MANAGER_JOB_ID_DROPDOWN.change(update_step_index, inputs = JOB_MANAGER_JOB_ID_DROPDOWN, outputs = JOB_MANAGER_STEP_INDEX_DROPDOWN)
71
+ JOB_MANAGER_APPLY_BUTTON.click(apply, inputs = [ JOB_MANAGER_JOB_ACTION_DROPDOWN, JOB_MANAGER_JOB_ID_TEXTBOX, JOB_MANAGER_JOB_ID_DROPDOWN, JOB_MANAGER_STEP_INDEX_DROPDOWN ], outputs = [ JOB_MANAGER_JOB_ACTION_DROPDOWN, JOB_MANAGER_JOB_ID_TEXTBOX, JOB_MANAGER_JOB_ID_DROPDOWN, JOB_MANAGER_STEP_INDEX_DROPDOWN ])
72
+
73
+ ui_workflow_dropdown = get_ui_component('ui_workflow_dropdown')
74
+ if ui_workflow_dropdown:
75
+ ui_workflow_dropdown.change(remote_update, inputs = ui_workflow_dropdown, outputs = [ JOB_MANAGER_WRAPPER, JOB_MANAGER_JOB_ACTION_DROPDOWN, JOB_MANAGER_JOB_ID_TEXTBOX, JOB_MANAGER_JOB_ID_DROPDOWN, JOB_MANAGER_STEP_INDEX_DROPDOWN ])
76
+
77
+
78
+ def remote_update(ui_workflow : UiWorkflow) -> Tuple[gradio.Row, gradio.Dropdown, gradio.Textbox, gradio.Dropdown, gradio.Dropdown]:
79
+ is_job_manager = ui_workflow == 'job_manager'
80
+ return gradio.Row(visible = is_job_manager), gradio.Dropdown(value = get_first(uis_choices.job_manager_actions)), gradio.Textbox(value = None, visible = True), gradio.Dropdown(visible = False), gradio.Dropdown(visible = False)
81
+
82
+
83
+ def apply(job_action : JobManagerAction, created_job_id : str, selected_job_id : str, selected_step_index : int) -> Tuple[gradio.Dropdown, gradio.Textbox, gradio.Dropdown, gradio.Dropdown]:
84
+ created_job_id = convert_str_none(created_job_id)
85
+ selected_job_id = convert_str_none(selected_job_id)
86
+ selected_step_index = convert_int_none(selected_step_index)
87
+ step_args = collect_step_args()
88
+ output_path = step_args.get('output_path')
89
+
90
+ if is_directory(step_args.get('output_path')):
91
+ step_args['output_path'] = suggest_output_path(step_args.get('output_path'), state_manager.get_item('target_path'))
92
+
93
+ if job_action == 'job-create':
94
+ if created_job_id and job_manager.create_job(created_job_id):
95
+ updated_job_ids = job_manager.find_job_ids('drafted') or [ 'none' ]
96
+
97
+ logger.info(translator.get('job_created').format(job_id = created_job_id), __name__)
98
+ return gradio.Dropdown(value = 'job-add-step'), gradio.Textbox(visible = False), gradio.Dropdown(value = created_job_id, choices = updated_job_ids, visible = True), gradio.Dropdown()
99
+ else:
100
+ logger.error(translator.get('job_not_created').format(job_id = created_job_id), __name__)
101
+
102
+ if job_action == 'job-submit':
103
+ if selected_job_id and job_manager.submit_job(selected_job_id):
104
+ updated_job_ids = job_manager.find_job_ids('drafted') or [ 'none' ]
105
+
106
+ logger.info(translator.get('job_submitted').format(job_id = selected_job_id), __name__)
107
+ return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids, visible = True), gradio.Dropdown()
108
+ else:
109
+ logger.error(translator.get('job_not_submitted').format(job_id = selected_job_id), __name__)
110
+
111
+ if job_action == 'job-delete':
112
+ if selected_job_id and job_manager.delete_job(selected_job_id):
113
+ updated_job_ids = job_manager.find_job_ids('drafted') + job_manager.find_job_ids('queued') + job_manager.find_job_ids('failed') + job_manager.find_job_ids('completed') or [ 'none' ]
114
+
115
+ logger.info(translator.get('job_deleted').format(job_id = selected_job_id), __name__)
116
+ return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids, visible = True), gradio.Dropdown()
117
+ else:
118
+ logger.error(translator.get('job_not_deleted').format(job_id = selected_job_id), __name__)
119
+
120
+ if job_action == 'job-add-step':
121
+ if selected_job_id and job_manager.add_step(selected_job_id, step_args):
122
+ state_manager.set_item('output_path', output_path)
123
+ logger.info(translator.get('job_step_added').format(job_id = selected_job_id), __name__)
124
+ return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(visible = True), gradio.Dropdown(visible = False)
125
+ else:
126
+ state_manager.set_item('output_path', output_path)
127
+ logger.error(translator.get('job_step_not_added').format(job_id = selected_job_id), __name__)
128
+
129
+ if job_action == 'job-remix-step':
130
+ if selected_job_id and job_manager.has_step(selected_job_id, selected_step_index) and job_manager.remix_step(selected_job_id, selected_step_index, step_args):
131
+ updated_step_choices = get_step_choices(selected_job_id) or [ 'none' ] #type:ignore[list-item]
132
+
133
+ state_manager.set_item('output_path', output_path)
134
+ logger.info(translator.get('job_remix_step_added').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
135
+ return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(visible = True), gradio.Dropdown(value = get_last(updated_step_choices), choices = updated_step_choices, visible = True)
136
+ else:
137
+ state_manager.set_item('output_path', output_path)
138
+ logger.error(translator.get('job_remix_step_not_added').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
139
+
140
+ if job_action == 'job-insert-step':
141
+ if selected_job_id and job_manager.has_step(selected_job_id, selected_step_index) and job_manager.insert_step(selected_job_id, selected_step_index, step_args):
142
+ updated_step_choices = get_step_choices(selected_job_id) or [ 'none' ] #type:ignore[list-item]
143
+
144
+ state_manager.set_item('output_path', output_path)
145
+ logger.info(translator.get('job_step_inserted').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
146
+ return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(visible = True), gradio.Dropdown(value = get_last(updated_step_choices), choices = updated_step_choices, visible = True)
147
+ else:
148
+ state_manager.set_item('output_path', output_path)
149
+ logger.error(translator.get('job_step_not_inserted').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
150
+
151
+ if job_action == 'job-remove-step':
152
+ if selected_job_id and job_manager.has_step(selected_job_id, selected_step_index) and job_manager.remove_step(selected_job_id, selected_step_index):
153
+ updated_step_choices = get_step_choices(selected_job_id) or [ 'none' ] #type:ignore[list-item]
154
+
155
+ logger.info(translator.get('job_step_removed').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
156
+ return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(visible = True), gradio.Dropdown(value = get_last(updated_step_choices), choices = updated_step_choices, visible = True)
157
+ else:
158
+ logger.error(translator.get('job_step_not_removed').format(job_id = selected_job_id, step_index = selected_step_index), __name__)
159
+ return gradio.Dropdown(), gradio.Textbox(), gradio.Dropdown(), gradio.Dropdown()
160
+
161
+
162
+ def get_step_choices(job_id : str) -> List[int]:
163
+ steps = job_manager.get_steps(job_id)
164
+ return [ index for index, _ in enumerate(steps) ]
165
+
166
+
167
+ def update(job_action : JobManagerAction, selected_job_id : str) -> Tuple[gradio.Textbox, gradio.Dropdown, gradio.Dropdown]:
168
+ if job_action == 'job-create':
169
+ return gradio.Textbox(value = None, visible = True), gradio.Dropdown(visible = False), gradio.Dropdown(visible = False)
170
+
171
+ if job_action == 'job-delete':
172
+ updated_job_ids = job_manager.find_job_ids('drafted') + job_manager.find_job_ids('queued') + job_manager.find_job_ids('failed') + job_manager.find_job_ids('completed') or [ 'none' ]
173
+ updated_job_id = selected_job_id if selected_job_id in updated_job_ids else get_last(updated_job_ids)
174
+
175
+ return gradio.Textbox(visible = False), gradio.Dropdown(value = updated_job_id, choices = updated_job_ids, visible = True), gradio.Dropdown(visible = False)
176
+
177
+ if job_action in [ 'job-submit', 'job-add-step' ]:
178
+ updated_job_ids = job_manager.find_job_ids('drafted') or [ 'none' ]
179
+ updated_job_id = selected_job_id if selected_job_id in updated_job_ids else get_last(updated_job_ids)
180
+
181
+ return gradio.Textbox(visible = False), gradio.Dropdown(value = updated_job_id, choices = updated_job_ids, visible = True), gradio.Dropdown(visible = False)
182
+
183
+ if job_action in [ 'job-remix-step', 'job-insert-step', 'job-remove-step' ]:
184
+ updated_job_ids = job_manager.find_job_ids('drafted') or [ 'none' ]
185
+ updated_job_id = selected_job_id if selected_job_id in updated_job_ids else get_last(updated_job_ids)
186
+ updated_step_choices = get_step_choices(updated_job_id) or [ 'none' ] #type:ignore[list-item]
187
+
188
+ return gradio.Textbox(visible = False), gradio.Dropdown(value = updated_job_id, choices = updated_job_ids, visible = True), gradio.Dropdown(value = get_last(updated_step_choices), choices = updated_step_choices, visible = True)
189
+ return gradio.Textbox(visible = False), gradio.Dropdown(visible = False), gradio.Dropdown(visible = False)
190
+
191
+
192
+ def update_step_index(job_id : str) -> gradio.Dropdown:
193
+ step_choices = get_step_choices(job_id) or [ 'none' ] #type:ignore[list-item]
194
+ return gradio.Dropdown(value = get_last(step_choices), choices = step_choices)
uis/components/job_runner.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from time import sleep
2
+ from typing import Optional, Tuple
3
+
4
+ import gradio
5
+
6
+ from facefusion import logger, process_manager, state_manager, translator
7
+ from facefusion.common_helper import get_first, get_last
8
+ from facefusion.core import process_step
9
+ from facefusion.jobs import job_manager, job_runner, job_store
10
+ from facefusion.types import UiWorkflow
11
+ from facefusion.uis import choices as uis_choices
12
+ from facefusion.uis.core import get_ui_component
13
+ from facefusion.uis.types import JobRunnerAction
14
+ from facefusion.uis.ui_helper import convert_str_none
15
+
16
+ JOB_RUNNER_WRAPPER : Optional[gradio.Column] = None
17
+ JOB_RUNNER_JOB_ACTION_DROPDOWN : Optional[gradio.Dropdown] = None
18
+ JOB_RUNNER_JOB_ID_DROPDOWN : Optional[gradio.Dropdown] = None
19
+ JOB_RUNNER_START_BUTTON : Optional[gradio.Button] = None
20
+ JOB_RUNNER_STOP_BUTTON : Optional[gradio.Button] = None
21
+
22
+
23
+ def render() -> None:
24
+ global JOB_RUNNER_WRAPPER
25
+ global JOB_RUNNER_JOB_ACTION_DROPDOWN
26
+ global JOB_RUNNER_JOB_ID_DROPDOWN
27
+ global JOB_RUNNER_START_BUTTON
28
+ global JOB_RUNNER_STOP_BUTTON
29
+
30
+ if job_manager.init_jobs(state_manager.get_item('jobs_path')):
31
+ is_job_runner = state_manager.get_item('ui_workflow') == 'job_runner'
32
+ queued_job_ids = job_manager.find_job_ids('queued') or [ 'none' ]
33
+
34
+ with gradio.Column(visible = is_job_runner) as JOB_RUNNER_WRAPPER:
35
+ JOB_RUNNER_JOB_ACTION_DROPDOWN = gradio.Dropdown(
36
+ label = translator.get('uis.job_runner_job_action_dropdown'),
37
+ choices = uis_choices.job_runner_actions,
38
+ value = get_first(uis_choices.job_runner_actions)
39
+ )
40
+ JOB_RUNNER_JOB_ID_DROPDOWN = gradio.Dropdown(
41
+ label = translator.get('uis.job_runner_job_id_dropdown'),
42
+ choices = queued_job_ids,
43
+ value = get_last(queued_job_ids)
44
+ )
45
+ with gradio.Row():
46
+ JOB_RUNNER_START_BUTTON = gradio.Button(
47
+ value = translator.get('uis.start_button'),
48
+ variant = 'primary',
49
+ size = 'sm'
50
+ )
51
+ JOB_RUNNER_STOP_BUTTON = gradio.Button(
52
+ value = translator.get('uis.stop_button'),
53
+ variant = 'primary',
54
+ size = 'sm',
55
+ visible = False
56
+ )
57
+
58
+
59
+ def listen() -> None:
60
+ JOB_RUNNER_JOB_ACTION_DROPDOWN.change(update_job_action, inputs = JOB_RUNNER_JOB_ACTION_DROPDOWN, outputs = JOB_RUNNER_JOB_ID_DROPDOWN)
61
+ JOB_RUNNER_START_BUTTON.click(start, outputs = [ JOB_RUNNER_START_BUTTON, JOB_RUNNER_STOP_BUTTON ])
62
+ JOB_RUNNER_START_BUTTON.click(run, inputs = [ JOB_RUNNER_JOB_ACTION_DROPDOWN, JOB_RUNNER_JOB_ID_DROPDOWN ], outputs = [ JOB_RUNNER_START_BUTTON, JOB_RUNNER_STOP_BUTTON, JOB_RUNNER_JOB_ID_DROPDOWN ])
63
+ JOB_RUNNER_STOP_BUTTON.click(stop, outputs = [ JOB_RUNNER_START_BUTTON, JOB_RUNNER_STOP_BUTTON ])
64
+
65
+ ui_workflow_dropdown = get_ui_component('ui_workflow_dropdown')
66
+ if ui_workflow_dropdown:
67
+ ui_workflow_dropdown.change(remote_update, inputs = ui_workflow_dropdown, outputs = [ JOB_RUNNER_WRAPPER, JOB_RUNNER_JOB_ACTION_DROPDOWN, JOB_RUNNER_JOB_ID_DROPDOWN ])
68
+
69
+
70
+ def remote_update(ui_workflow : UiWorkflow) -> Tuple[gradio.Row, gradio.Dropdown, gradio.Dropdown]:
71
+ is_job_runner = ui_workflow == 'job_runner'
72
+ queued_job_ids = job_manager.find_job_ids('queued') or [ 'none' ]
73
+
74
+ return gradio.Row(visible = is_job_runner), gradio.Dropdown(value = get_first(uis_choices.job_runner_actions), choices = uis_choices.job_runner_actions), gradio.Dropdown(value = get_last(queued_job_ids), choices = queued_job_ids)
75
+
76
+
77
+ def start() -> Tuple[gradio.Button, gradio.Button]:
78
+ while not process_manager.is_processing():
79
+ sleep(0.5)
80
+ return gradio.Button(visible = False), gradio.Button(visible = True)
81
+
82
+
83
+ def run(job_action : JobRunnerAction, job_id : str) -> Tuple[gradio.Button, gradio.Button, gradio.Dropdown]:
84
+ job_id = convert_str_none(job_id)
85
+
86
+ for key in job_store.get_job_keys():
87
+ state_manager.sync_item(key) #type:ignore[arg-type]
88
+
89
+ if job_action == 'job-run':
90
+ logger.info(translator.get('running_job').format(job_id = job_id), __name__)
91
+ if job_id and job_runner.run_job(job_id, process_step):
92
+ logger.info(translator.get('processing_job_succeeded').format(job_id = job_id), __name__)
93
+ else:
94
+ logger.info(translator.get('processing_job_failed').format(job_id = job_id), __name__)
95
+ updated_job_ids = job_manager.find_job_ids('queued') or [ 'none' ]
96
+
97
+ return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids)
98
+
99
+ if job_action == 'job-run-all':
100
+ logger.info(translator.get('running_jobs'), __name__)
101
+ halt_on_error = False
102
+ if job_runner.run_jobs(process_step, halt_on_error):
103
+ logger.info(translator.get('processing_jobs_succeeded'), __name__)
104
+ else:
105
+ logger.info(translator.get('processing_jobs_failed'), __name__)
106
+
107
+ if job_action == 'job-retry':
108
+ logger.info(translator.get('retrying_job').format(job_id = job_id), __name__)
109
+ if job_id and job_runner.retry_job(job_id, process_step):
110
+ logger.info(translator.get('processing_job_succeeded').format(job_id = job_id), __name__)
111
+ else:
112
+ logger.info(translator.get('processing_job_failed').format(job_id = job_id), __name__)
113
+ updated_job_ids = job_manager.find_job_ids('failed') or [ 'none' ]
114
+
115
+ return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids)
116
+
117
+ if job_action == 'job-retry-all':
118
+ logger.info(translator.get('retrying_jobs'), __name__)
119
+ halt_on_error = False
120
+ if job_runner.retry_jobs(process_step, halt_on_error):
121
+ logger.info(translator.get('processing_jobs_succeeded'), __name__)
122
+ else:
123
+ logger.info(translator.get('processing_jobs_failed'), __name__)
124
+ return gradio.Button(visible = True), gradio.Button(visible = False), gradio.Dropdown()
125
+
126
+
127
+ def stop() -> Tuple[gradio.Button, gradio.Button]:
128
+ process_manager.stop()
129
+ return gradio.Button(visible = True), gradio.Button(visible = False)
130
+
131
+
132
+ def update_job_action(job_action : JobRunnerAction) -> gradio.Dropdown:
133
+ if job_action == 'job-run':
134
+ updated_job_ids = job_manager.find_job_ids('queued') or [ 'none' ]
135
+
136
+ return gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids, visible = True)
137
+
138
+ if job_action == 'job-retry':
139
+ updated_job_ids = job_manager.find_job_ids('failed') or [ 'none' ]
140
+
141
+ return gradio.Dropdown(value = get_last(updated_job_ids), choices = updated_job_ids, visible = True)
142
+ return gradio.Dropdown(visible = False)
uis/components/lip_syncer_options.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.common_helper import calculate_float_step
7
+ from facefusion.processors.core import load_processor_module
8
+ from facefusion.processors.modules.lip_syncer import choices as lip_syncer_choices
9
+ from facefusion.processors.modules.lip_syncer.types import LipSyncerModel, LipSyncerWeight
10
+ from facefusion.uis.core import get_ui_component, register_ui_component
11
+
12
+ LIP_SYNCER_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
13
+ LIP_SYNCER_WEIGHT_SLIDER : Optional[gradio.Slider] = None
14
+
15
+
16
+ def render() -> None:
17
+ global LIP_SYNCER_MODEL_DROPDOWN
18
+ global LIP_SYNCER_WEIGHT_SLIDER
19
+
20
+ has_lip_syncer = 'lip_syncer' in state_manager.get_item('processors')
21
+ LIP_SYNCER_MODEL_DROPDOWN = gradio.Dropdown(
22
+ label = translator.get('uis.model_dropdown', 'facefusion.processors.modules.lip_syncer'),
23
+ choices = lip_syncer_choices.lip_syncer_models,
24
+ value = state_manager.get_item('lip_syncer_model'),
25
+ visible = has_lip_syncer
26
+ )
27
+ LIP_SYNCER_WEIGHT_SLIDER = gradio.Slider(
28
+ label = translator.get('uis.weight_slider', 'facefusion.processors.modules.lip_syncer'),
29
+ value = state_manager.get_item('lip_syncer_weight'),
30
+ step = calculate_float_step(lip_syncer_choices.lip_syncer_weight_range),
31
+ minimum = lip_syncer_choices.lip_syncer_weight_range[0],
32
+ maximum = lip_syncer_choices.lip_syncer_weight_range[-1],
33
+ visible = has_lip_syncer
34
+ )
35
+ register_ui_component('lip_syncer_model_dropdown', LIP_SYNCER_MODEL_DROPDOWN)
36
+ register_ui_component('lip_syncer_weight_slider', LIP_SYNCER_WEIGHT_SLIDER)
37
+
38
+
39
+ def listen() -> None:
40
+ LIP_SYNCER_MODEL_DROPDOWN.change(update_lip_syncer_model, inputs = LIP_SYNCER_MODEL_DROPDOWN, outputs = LIP_SYNCER_MODEL_DROPDOWN)
41
+ LIP_SYNCER_WEIGHT_SLIDER.release(update_lip_syncer_weight, inputs = LIP_SYNCER_WEIGHT_SLIDER)
42
+
43
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
44
+ if processors_checkbox_group:
45
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = [ LIP_SYNCER_MODEL_DROPDOWN, LIP_SYNCER_WEIGHT_SLIDER ])
46
+
47
+
48
+ def remote_update(processors : List[str]) -> Tuple[gradio.Dropdown, gradio.Slider]:
49
+ has_lip_syncer = 'lip_syncer' in processors
50
+ return gradio.Dropdown(visible = has_lip_syncer), gradio.Slider(visible = has_lip_syncer)
51
+
52
+
53
+ def update_lip_syncer_model(lip_syncer_model : LipSyncerModel) -> gradio.Dropdown:
54
+ lip_syncer_module = load_processor_module('lip_syncer')
55
+ lip_syncer_module.clear_inference_pool()
56
+ state_manager.set_item('lip_syncer_model', lip_syncer_model)
57
+
58
+ if lip_syncer_module.pre_check():
59
+ return gradio.Dropdown(value = state_manager.get_item('lip_syncer_model'))
60
+ return gradio.Dropdown()
61
+
62
+
63
+ def update_lip_syncer_weight(lip_syncer_weight : LipSyncerWeight) -> None:
64
+ state_manager.set_item('lip_syncer_weight', lip_syncer_weight)
uis/components/memory.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import state_manager, translator
7
+ from facefusion.types import VideoMemoryStrategy
8
+
9
+ VIDEO_MEMORY_STRATEGY_DROPDOWN : Optional[gradio.Dropdown] = None
10
+
11
+
12
+ def render() -> None:
13
+ global VIDEO_MEMORY_STRATEGY_DROPDOWN
14
+
15
+ VIDEO_MEMORY_STRATEGY_DROPDOWN = gradio.Dropdown(
16
+ label = translator.get('uis.video_memory_strategy_dropdown'),
17
+ choices = facefusion.choices.video_memory_strategies,
18
+ value = state_manager.get_item('video_memory_strategy')
19
+ )
20
+
21
+
22
+ def listen() -> None:
23
+ VIDEO_MEMORY_STRATEGY_DROPDOWN.change(update_video_memory_strategy, inputs = VIDEO_MEMORY_STRATEGY_DROPDOWN)
24
+
25
+
26
+ def update_video_memory_strategy(video_memory_strategy : VideoMemoryStrategy) -> None:
27
+ state_manager.set_item('video_memory_strategy', video_memory_strategy)
uis/components/output.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import tempfile
2
+ from pathlib import Path
3
+ from typing import Optional
4
+
5
+ import gradio
6
+
7
+ from facefusion import state_manager, translator
8
+ from facefusion.uis.core import register_ui_component
9
+
10
+ OUTPUT_PATH_TEXTBOX : Optional[gradio.Textbox] = None
11
+ OUTPUT_IMAGE : Optional[gradio.Image] = None
12
+ OUTPUT_VIDEO : Optional[gradio.Video] = None
13
+
14
+
15
+ def render() -> None:
16
+ global OUTPUT_PATH_TEXTBOX
17
+ global OUTPUT_IMAGE
18
+ global OUTPUT_VIDEO
19
+
20
+ if not state_manager.get_item('output_path'):
21
+ documents_directory = Path.home().joinpath('Documents')
22
+
23
+ if documents_directory.exists():
24
+ state_manager.set_item('output_path', documents_directory)
25
+ else:
26
+ state_manager.set_item('output_path', tempfile.gettempdir())
27
+ OUTPUT_PATH_TEXTBOX = gradio.Textbox(
28
+ label = translator.get('uis.output_path_textbox'),
29
+ value = state_manager.get_item('output_path'),
30
+ max_lines = 1
31
+ )
32
+ OUTPUT_IMAGE = gradio.Image(
33
+ label = translator.get('uis.output_image_or_video'),
34
+ visible = False
35
+ )
36
+ OUTPUT_VIDEO = gradio.Video(
37
+ label = translator.get('uis.output_image_or_video')
38
+ )
39
+
40
+
41
+ def listen() -> None:
42
+ OUTPUT_PATH_TEXTBOX.change(update_output_path, inputs = OUTPUT_PATH_TEXTBOX)
43
+ register_ui_component('output_image', OUTPUT_IMAGE)
44
+ register_ui_component('output_video', OUTPUT_VIDEO)
45
+
46
+
47
+ def update_output_path(output_path : str) -> None:
48
+ state_manager.set_item('output_path', output_path)
uis/components/output_options.py ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import state_manager, translator
7
+ from facefusion.common_helper import calculate_float_step, calculate_int_step
8
+ from facefusion.ffmpeg import get_available_encoder_set
9
+ from facefusion.filesystem import is_image, is_video
10
+ from facefusion.types import AudioEncoder, Fps, Scale, VideoEncoder, VideoPreset
11
+ from facefusion.uis.core import get_ui_components, register_ui_component
12
+ from facefusion.vision import detect_video_fps
13
+
14
+ OUTPUT_IMAGE_QUALITY_SLIDER : Optional[gradio.Slider] = None
15
+ OUTPUT_IMAGE_SCALE_SLIDER : Optional[gradio.Slider] = None
16
+ OUTPUT_AUDIO_ENCODER_DROPDOWN : Optional[gradio.Dropdown] = None
17
+ OUTPUT_AUDIO_QUALITY_SLIDER : Optional[gradio.Slider] = None
18
+ OUTPUT_AUDIO_VOLUME_SLIDER : Optional[gradio.Slider] = None
19
+ OUTPUT_VIDEO_ENCODER_DROPDOWN : Optional[gradio.Dropdown] = None
20
+ OUTPUT_VIDEO_PRESET_DROPDOWN : Optional[gradio.Dropdown] = None
21
+ OUTPUT_VIDEO_SCALE_SLIDER : Optional[gradio.Slider] = None
22
+ OUTPUT_VIDEO_QUALITY_SLIDER : Optional[gradio.Slider] = None
23
+ OUTPUT_VIDEO_FPS_SLIDER : Optional[gradio.Slider] = None
24
+
25
+
26
+ def render() -> None:
27
+ global OUTPUT_IMAGE_QUALITY_SLIDER
28
+ global OUTPUT_IMAGE_SCALE_SLIDER
29
+ global OUTPUT_AUDIO_ENCODER_DROPDOWN
30
+ global OUTPUT_AUDIO_QUALITY_SLIDER
31
+ global OUTPUT_AUDIO_VOLUME_SLIDER
32
+ global OUTPUT_VIDEO_ENCODER_DROPDOWN
33
+ global OUTPUT_VIDEO_PRESET_DROPDOWN
34
+ global OUTPUT_VIDEO_SCALE_SLIDER
35
+ global OUTPUT_VIDEO_QUALITY_SLIDER
36
+ global OUTPUT_VIDEO_FPS_SLIDER
37
+
38
+ available_encoder_set = get_available_encoder_set()
39
+
40
+ OUTPUT_IMAGE_QUALITY_SLIDER = gradio.Slider(
41
+ label = translator.get('uis.output_image_quality_slider'),
42
+ value = state_manager.get_item('output_image_quality'),
43
+ step = calculate_int_step(facefusion.choices.output_image_quality_range),
44
+ minimum = facefusion.choices.output_image_quality_range[0],
45
+ maximum = facefusion.choices.output_image_quality_range[-1],
46
+ visible = is_image(state_manager.get_item('target_path'))
47
+ )
48
+ OUTPUT_IMAGE_SCALE_SLIDER = gradio.Slider(
49
+ label = translator.get('uis.output_image_scale_slider'),
50
+ step = calculate_float_step(facefusion.choices.output_image_scale_range),
51
+ value = state_manager.get_item('output_image_scale'),
52
+ minimum = facefusion.choices.output_image_scale_range[0],
53
+ maximum = facefusion.choices.output_image_scale_range[-1],
54
+ visible = is_image(state_manager.get_item('target_path'))
55
+ )
56
+ OUTPUT_AUDIO_ENCODER_DROPDOWN = gradio.Dropdown(
57
+ label = translator.get('uis.output_audio_encoder_dropdown'),
58
+ choices = available_encoder_set.get('audio'),
59
+ value = state_manager.get_item('output_audio_encoder'),
60
+ visible = is_video(state_manager.get_item('target_path'))
61
+ )
62
+ OUTPUT_AUDIO_QUALITY_SLIDER = gradio.Slider(
63
+ label = translator.get('uis.output_audio_quality_slider'),
64
+ value = state_manager.get_item('output_audio_quality'),
65
+ step = calculate_int_step(facefusion.choices.output_audio_quality_range),
66
+ minimum = facefusion.choices.output_audio_quality_range[0],
67
+ maximum = facefusion.choices.output_audio_quality_range[-1],
68
+ visible = is_video(state_manager.get_item('target_path'))
69
+ )
70
+ OUTPUT_AUDIO_VOLUME_SLIDER = gradio.Slider(
71
+ label = translator.get('uis.output_audio_volume_slider'),
72
+ value = state_manager.get_item('output_audio_volume'),
73
+ step = calculate_int_step(facefusion.choices.output_audio_volume_range),
74
+ minimum = facefusion.choices.output_audio_volume_range[0],
75
+ maximum = facefusion.choices.output_audio_volume_range[-1],
76
+ visible = is_video(state_manager.get_item('target_path'))
77
+ )
78
+ OUTPUT_VIDEO_ENCODER_DROPDOWN = gradio.Dropdown(
79
+ label = translator.get('uis.output_video_encoder_dropdown'),
80
+ choices = available_encoder_set.get('video'),
81
+ value = state_manager.get_item('output_video_encoder'),
82
+ visible = is_video(state_manager.get_item('target_path'))
83
+ )
84
+ OUTPUT_VIDEO_PRESET_DROPDOWN = gradio.Dropdown(
85
+ label = translator.get('uis.output_video_preset_dropdown'),
86
+ choices = facefusion.choices.output_video_presets,
87
+ value = state_manager.get_item('output_video_preset'),
88
+ visible = is_video(state_manager.get_item('target_path'))
89
+ )
90
+ OUTPUT_VIDEO_QUALITY_SLIDER = gradio.Slider(
91
+ label = translator.get('uis.output_video_quality_slider'),
92
+ value = state_manager.get_item('output_video_quality'),
93
+ step = calculate_int_step(facefusion.choices.output_video_quality_range),
94
+ minimum = facefusion.choices.output_video_quality_range[0],
95
+ maximum = facefusion.choices.output_video_quality_range[-1],
96
+ visible = is_video(state_manager.get_item('target_path'))
97
+ )
98
+ OUTPUT_VIDEO_SCALE_SLIDER = gradio.Slider(
99
+ label = translator.get('uis.output_video_scale_slider'),
100
+ step = calculate_float_step(facefusion.choices.output_video_scale_range),
101
+ value = state_manager.get_item('output_video_scale'),
102
+ minimum = facefusion.choices.output_video_scale_range[0],
103
+ maximum = facefusion.choices.output_video_scale_range[-1],
104
+ visible = is_video(state_manager.get_item('target_path'))
105
+ )
106
+ OUTPUT_VIDEO_FPS_SLIDER = gradio.Slider(
107
+ label = translator.get('uis.output_video_fps_slider'),
108
+ value = state_manager.get_item('output_video_fps'),
109
+ step = 0.01,
110
+ minimum = 1,
111
+ maximum = 60,
112
+ visible = is_video(state_manager.get_item('target_path'))
113
+ )
114
+ register_ui_component('output_video_fps_slider', OUTPUT_VIDEO_FPS_SLIDER)
115
+
116
+
117
+ def listen() -> None:
118
+ OUTPUT_IMAGE_QUALITY_SLIDER.release(update_output_image_quality, inputs = OUTPUT_IMAGE_QUALITY_SLIDER)
119
+ OUTPUT_IMAGE_SCALE_SLIDER.release(update_output_image_scale, inputs = OUTPUT_IMAGE_SCALE_SLIDER)
120
+ OUTPUT_AUDIO_ENCODER_DROPDOWN.change(update_output_audio_encoder, inputs = OUTPUT_AUDIO_ENCODER_DROPDOWN)
121
+ OUTPUT_AUDIO_QUALITY_SLIDER.release(update_output_audio_quality, inputs = OUTPUT_AUDIO_QUALITY_SLIDER)
122
+ OUTPUT_AUDIO_VOLUME_SLIDER.release(update_output_audio_volume, inputs = OUTPUT_AUDIO_VOLUME_SLIDER)
123
+ OUTPUT_VIDEO_ENCODER_DROPDOWN.change(update_output_video_encoder, inputs = OUTPUT_VIDEO_ENCODER_DROPDOWN)
124
+ OUTPUT_VIDEO_PRESET_DROPDOWN.change(update_output_video_preset, inputs = OUTPUT_VIDEO_PRESET_DROPDOWN)
125
+ OUTPUT_VIDEO_QUALITY_SLIDER.release(update_output_video_quality, inputs = OUTPUT_VIDEO_QUALITY_SLIDER)
126
+ OUTPUT_VIDEO_SCALE_SLIDER.release(update_output_video_scale, inputs = OUTPUT_VIDEO_SCALE_SLIDER)
127
+ OUTPUT_VIDEO_FPS_SLIDER.release(update_output_video_fps, inputs = OUTPUT_VIDEO_FPS_SLIDER)
128
+
129
+ for ui_component in get_ui_components(
130
+ [
131
+ 'target_image',
132
+ 'target_video'
133
+ ]):
134
+ for method in [ 'change', 'clear' ]:
135
+ getattr(ui_component, method)(remote_update, outputs = [ OUTPUT_IMAGE_QUALITY_SLIDER, OUTPUT_IMAGE_SCALE_SLIDER, OUTPUT_AUDIO_ENCODER_DROPDOWN, OUTPUT_AUDIO_QUALITY_SLIDER, OUTPUT_AUDIO_VOLUME_SLIDER, OUTPUT_VIDEO_ENCODER_DROPDOWN, OUTPUT_VIDEO_PRESET_DROPDOWN, OUTPUT_VIDEO_QUALITY_SLIDER, OUTPUT_VIDEO_SCALE_SLIDER, OUTPUT_VIDEO_FPS_SLIDER ])
136
+
137
+
138
+ def remote_update() -> Tuple[gradio.Slider, gradio.Slider, gradio.Dropdown, gradio.Slider, gradio.Slider, gradio.Dropdown, gradio.Dropdown, gradio.Slider, gradio.Slider, gradio.Slider]:
139
+ if is_image(state_manager.get_item('target_path')):
140
+ return gradio.Slider(visible = True), gradio.Slider(visible = True), gradio.Dropdown(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Dropdown(visible = False), gradio.Dropdown(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False)
141
+ if is_video(state_manager.get_item('target_path')):
142
+ state_manager.set_item('output_video_fps', detect_video_fps(state_manager.get_item('target_path')))
143
+ return gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Dropdown(visible = True), gradio.Slider(visible = True), gradio.Slider(visible = True), gradio.Dropdown(visible = True), gradio.Dropdown(visible = True), gradio.Slider(visible = True), gradio.Slider(visible = True), gradio.Slider(value = state_manager.get_item('output_video_fps'), visible = True)
144
+ return gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Dropdown(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Dropdown(visible = False), gradio.Dropdown(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False), gradio.Slider(visible = False)
145
+
146
+
147
+ def update_output_image_quality(output_image_quality : float) -> None:
148
+ state_manager.set_item('output_image_quality', int(output_image_quality))
149
+
150
+
151
+ def update_output_image_scale(output_image_scale : Scale) -> None:
152
+ state_manager.set_item('output_image_scale', output_image_scale)
153
+
154
+
155
+ def update_output_audio_encoder(output_audio_encoder : AudioEncoder) -> None:
156
+ state_manager.set_item('output_audio_encoder', output_audio_encoder)
157
+
158
+
159
+ def update_output_audio_quality(output_audio_quality : float) -> None:
160
+ state_manager.set_item('output_audio_quality', int(output_audio_quality))
161
+
162
+
163
+ def update_output_audio_volume(output_audio_volume: float) -> None:
164
+ state_manager.set_item('output_audio_volume', int(output_audio_volume))
165
+
166
+
167
+ def update_output_video_encoder(output_video_encoder : VideoEncoder) -> None:
168
+ state_manager.set_item('output_video_encoder', output_video_encoder)
169
+
170
+
171
+ def update_output_video_preset(output_video_preset : VideoPreset) -> None:
172
+ state_manager.set_item('output_video_preset', output_video_preset)
173
+
174
+
175
+ def update_output_video_quality(output_video_quality : float) -> None:
176
+ state_manager.set_item('output_video_quality', int(output_video_quality))
177
+
178
+
179
+ def update_output_video_scale(output_video_scale : Scale) -> None:
180
+ state_manager.set_item('output_video_scale', output_video_scale)
181
+
182
+
183
+ def update_output_video_fps(output_video_fps : Fps) -> None:
184
+ state_manager.set_item('output_video_fps', output_video_fps)
uis/components/preview.py ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from time import sleep
2
+ from typing import List, Optional, Tuple
3
+
4
+ import cv2
5
+ import gradio
6
+ import numpy
7
+
8
+ from facefusion import logger, process_manager, state_manager, translator
9
+ from facefusion.audio import create_empty_audio_frame, get_voice_frame
10
+ from facefusion.common_helper import get_first, get_middle
11
+ from facefusion.content_analyser import analyse_frame
12
+ from facefusion.face_creator import get_one_face
13
+ from facefusion.face_selector import select_faces
14
+ from facefusion.face_store import clear_faces
15
+ from facefusion.filesystem import filter_audio_paths, is_image, is_video
16
+ from facefusion.processors.core import get_processors_modules
17
+ from facefusion.types import AudioFrame, Face, Mask, VisionFrame
18
+ from facefusion.uis import choices as uis_choices
19
+ from facefusion.uis.core import get_ui_component, get_ui_components, register_ui_component
20
+ from facefusion.uis.types import ComponentOptions, PreviewMode
21
+ from facefusion.vision import detect_frame_orientation, extract_vision_mask, fit_cover_frame, is_vision_frame, merge_vision_mask, obscure_frame, read_static_image, read_static_images, read_video_frame, restrict_frame, select_video_frames, unpack_resolution
22
+
23
+ PREVIEW_IMAGE : Optional[gradio.Image] = None
24
+
25
+
26
+ def render() -> None:
27
+ global PREVIEW_IMAGE
28
+
29
+ preview_image_options : ComponentOptions =\
30
+ {
31
+ 'label': translator.get('uis.preview_image')
32
+ }
33
+
34
+ source_vision_frames = read_static_images(state_manager.get_item('source_paths'))
35
+ source_audio_path = get_first(filter_audio_paths(state_manager.get_item('source_paths')))
36
+ source_audio_frame = create_empty_audio_frame()
37
+ source_voice_frame = create_empty_audio_frame()
38
+
39
+ if source_audio_path and state_manager.get_item('output_video_fps'):
40
+ temp_voice_frame = get_voice_frame(source_audio_path, state_manager.get_item('output_video_fps'), state_manager.get_item('reference_frame_number'))
41
+ if numpy.any(temp_voice_frame):
42
+ source_voice_frame = temp_voice_frame
43
+
44
+ if is_image(state_manager.get_item('target_path')):
45
+ target_vision_frame = read_static_image(state_manager.get_item('target_path'))
46
+ reference_vision_frame = read_static_image(state_manager.get_item('target_path'))
47
+ preview_vision_frame = process_preview_frame(reference_vision_frame, source_vision_frames, source_audio_frame, source_voice_frame, [ target_vision_frame ], uis_choices.preview_modes[0], uis_choices.preview_resolutions[-1])
48
+ preview_image_options['value'] = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGR2RGB)
49
+ preview_image_options['elem_classes'] = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ]
50
+
51
+ if is_video(state_manager.get_item('target_path')):
52
+ reference_vision_frame = read_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
53
+ target_vision_frames = select_video_frames(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'), state_manager.get_item('target_frame_amount'))
54
+ preview_vision_frame = process_preview_frame(reference_vision_frame, source_vision_frames, source_audio_frame, source_voice_frame, target_vision_frames, uis_choices.preview_modes[0], uis_choices.preview_resolutions[-1])
55
+ preview_image_options['value'] = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGR2RGB)
56
+ preview_image_options['elem_classes'] = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ]
57
+ preview_image_options['visible'] = True
58
+ PREVIEW_IMAGE = gradio.Image(**preview_image_options)
59
+ register_ui_component('preview_image', PREVIEW_IMAGE)
60
+
61
+
62
+ def listen() -> None:
63
+ preview_frame_slider = get_ui_component('preview_frame_slider')
64
+ preview_mode_dropdown = get_ui_component('preview_mode_dropdown')
65
+ preview_resolution_dropdown = get_ui_component('preview_resolution_dropdown')
66
+
67
+ if preview_mode_dropdown:
68
+ preview_mode_dropdown.change(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
69
+
70
+ if preview_resolution_dropdown:
71
+ preview_resolution_dropdown.change(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
72
+
73
+ if preview_frame_slider:
74
+ preview_frame_slider.release(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE, show_progress = 'hidden')
75
+ preview_frame_slider.change(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE, show_progress = 'hidden', trigger_mode = 'once')
76
+
77
+ reference_face_position_gallery = get_ui_component('reference_face_position_gallery')
78
+ if reference_face_position_gallery:
79
+ reference_face_position_gallery.select(clear_and_update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
80
+
81
+ for ui_component in get_ui_components(
82
+ [
83
+ 'source_audio',
84
+ 'source_image',
85
+ 'target_image',
86
+ 'target_video'
87
+ ]):
88
+ for method in [ 'change', 'clear' ]:
89
+ getattr(ui_component, method)(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
90
+
91
+ for ui_component in get_ui_components(
92
+ [
93
+ 'background_remover_fill_color_red_number',
94
+ 'background_remover_fill_color_green_number',
95
+ 'background_remover_fill_color_blue_number',
96
+ 'background_remover_fill_color_alpha_number',
97
+ 'background_remover_despill_color_red_number',
98
+ 'background_remover_despill_color_green_number',
99
+ 'background_remover_despill_color_blue_number',
100
+ 'background_remover_despill_color_alpha_number',
101
+ 'face_debugger_items_checkbox_group',
102
+ 'frame_colorizer_size_dropdown',
103
+ 'face_mask_types_checkbox_group',
104
+ 'face_mask_areas_checkbox_group',
105
+ 'face_mask_regions_checkbox_group',
106
+ 'expression_restorer_areas_checkbox_group'
107
+ ]):
108
+ ui_component.change(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
109
+
110
+ for ui_component in get_ui_components(
111
+ [
112
+ 'age_modifier_direction_slider',
113
+ 'deep_swapper_morph_slider',
114
+ 'expression_restorer_factor_slider',
115
+ 'face_editor_eyebrow_direction_slider',
116
+ 'face_editor_eye_gaze_horizontal_slider',
117
+ 'face_editor_eye_gaze_vertical_slider',
118
+ 'face_editor_eye_open_ratio_slider',
119
+ 'face_editor_lip_open_ratio_slider',
120
+ 'face_editor_mouth_grim_slider',
121
+ 'face_editor_mouth_pout_slider',
122
+ 'face_editor_mouth_purse_slider',
123
+ 'face_editor_mouth_smile_slider',
124
+ 'face_editor_mouth_position_horizontal_slider',
125
+ 'face_editor_mouth_position_vertical_slider',
126
+ 'face_editor_head_pitch_slider',
127
+ 'face_editor_head_yaw_slider',
128
+ 'face_editor_head_roll_slider',
129
+ 'face_enhancer_blend_slider',
130
+ 'face_enhancer_weight_slider',
131
+ 'face_swapper_weight_slider',
132
+ 'frame_colorizer_blend_slider',
133
+ 'frame_enhancer_blend_slider',
134
+ 'lip_syncer_weight_slider',
135
+ 'reference_face_distance_slider',
136
+ 'face_selector_age_range_slider',
137
+ 'face_tracker_score_slider',
138
+ 'face_mask_blur_slider',
139
+ 'face_mask_padding_top_slider',
140
+ 'face_mask_padding_bottom_slider',
141
+ 'face_mask_padding_left_slider',
142
+ 'face_mask_padding_right_slider',
143
+ 'output_video_fps_slider'
144
+ ]):
145
+ ui_component.release(update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
146
+
147
+ for ui_component in get_ui_components(
148
+ [
149
+ 'age_modifier_model_dropdown',
150
+ 'background_remover_model_dropdown',
151
+ 'deep_swapper_model_dropdown',
152
+ 'expression_restorer_model_dropdown',
153
+ 'processors_checkbox_group',
154
+ 'face_editor_model_dropdown',
155
+ 'face_enhancer_model_dropdown',
156
+ 'face_swapper_model_dropdown',
157
+ 'face_swapper_pixel_boost_dropdown',
158
+ 'frame_colorizer_model_dropdown',
159
+ 'frame_enhancer_model_dropdown',
160
+ 'lip_syncer_model_dropdown',
161
+ 'face_selector_mode_dropdown',
162
+ 'face_selector_order_dropdown',
163
+ 'face_selector_gender_dropdown',
164
+ 'face_selector_race_dropdown',
165
+ 'face_detector_model_dropdown',
166
+ 'face_detector_size_dropdown',
167
+ 'face_detector_angles_checkbox_group',
168
+ 'face_landmarker_model_dropdown',
169
+ 'face_occluder_model_dropdown',
170
+ 'face_parser_model_dropdown',
171
+ 'voice_extractor_model_dropdown'
172
+ ]):
173
+ ui_component.change(clear_and_update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
174
+
175
+ for ui_component in get_ui_components(
176
+ [
177
+ 'face_detector_margin_slider',
178
+ 'face_detector_score_slider',
179
+ 'face_landmarker_score_slider'
180
+ ]):
181
+ ui_component.release(clear_and_update_preview_image, inputs = [ preview_mode_dropdown, preview_resolution_dropdown, preview_frame_slider ], outputs = PREVIEW_IMAGE)
182
+
183
+
184
+ def update_preview_image(preview_mode : PreviewMode, preview_resolution : str, frame_number : int = 0) -> gradio.Image:
185
+ while process_manager.is_checking():
186
+ sleep(0.5)
187
+
188
+ source_vision_frames = read_static_images(state_manager.get_item('source_paths'))
189
+ source_audio_path = get_first(filter_audio_paths(state_manager.get_item('source_paths')))
190
+ source_audio_frame = create_empty_audio_frame()
191
+ source_voice_frame = create_empty_audio_frame()
192
+
193
+ if source_audio_path and state_manager.get_item('output_video_fps'):
194
+ audio_frame_number = frame_number
195
+ if state_manager.get_item('trim_frame_start'):
196
+ audio_frame_number -= state_manager.get_item('trim_frame_start')
197
+ temp_voice_frame = get_voice_frame(source_audio_path, state_manager.get_item('output_video_fps'), audio_frame_number)
198
+ if numpy.any(temp_voice_frame):
199
+ source_voice_frame = temp_voice_frame
200
+
201
+ if is_image(state_manager.get_item('target_path')):
202
+ reference_vision_frame = read_static_image(state_manager.get_item('target_path'))
203
+ target_vision_frame = read_static_image(state_manager.get_item('target_path'), 'rgba')
204
+ preview_vision_frame = process_preview_frame(reference_vision_frame, source_vision_frames, source_audio_frame, source_voice_frame, [ target_vision_frame ], preview_mode, preview_resolution)
205
+ preview_vision_frame = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGRA2RGBA)
206
+ return gradio.Image(value = preview_vision_frame, elem_classes = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ])
207
+
208
+ if is_video(state_manager.get_item('target_path')):
209
+ reference_vision_frame = read_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
210
+ target_vision_frames = select_video_frames(state_manager.get_item('target_path'), frame_number, state_manager.get_item('target_frame_amount'))
211
+ preview_vision_frame = process_preview_frame(reference_vision_frame, source_vision_frames, source_audio_frame, source_voice_frame, target_vision_frames, preview_mode, preview_resolution)
212
+ preview_vision_frame = cv2.cvtColor(preview_vision_frame, cv2.COLOR_BGRA2RGBA)
213
+ return gradio.Image(value = preview_vision_frame, elem_classes = [ 'image-preview', 'is-' + detect_frame_orientation(preview_vision_frame) ])
214
+ return gradio.Image(value = None, elem_classes = None)
215
+
216
+
217
+ def clear_and_update_preview_image(preview_mode : PreviewMode, preview_resolution : str, frame_number : int = 0) -> gradio.Image:
218
+ clear_faces()
219
+ return update_preview_image(preview_mode, preview_resolution, frame_number)
220
+
221
+
222
+ def process_preview_frame(reference_vision_frame : VisionFrame, source_vision_frames : List[VisionFrame], source_audio_frame : AudioFrame, source_voice_frame : AudioFrame, target_vision_frames : List[VisionFrame], preview_mode : PreviewMode, preview_resolution : str) -> VisionFrame:
223
+ target_vision_frame = get_middle(target_vision_frames)
224
+ target_vision_frame = restrict_frame(target_vision_frame, unpack_resolution(preview_resolution))
225
+ temp_vision_mask = extract_vision_mask(target_vision_frame)
226
+ target_vision_frame = merge_vision_mask(target_vision_frame, temp_vision_mask)
227
+ target_vision_frames = [ restrict_frame(vision_frame, unpack_resolution(preview_resolution))[:, :, :3] for vision_frame in target_vision_frames ]
228
+ temp_vision_frame = target_vision_frame.copy()
229
+
230
+ if analyse_frame(target_vision_frame[:, :, :3]):
231
+ if preview_mode == 'frame-by-frame':
232
+ temp_vision_frame = obscure_frame(temp_vision_frame[:, :, :3])
233
+ return numpy.hstack((temp_vision_frame, temp_vision_frame))
234
+
235
+ if preview_mode == 'face-by-face':
236
+ target_crop_vision_frame, output_crop_vision_frame = create_face_by_face(reference_vision_frame, source_vision_frames, target_vision_frame[:, :, :3], temp_vision_frame[:, :, :3])
237
+ target_crop_vision_frame = obscure_frame(target_crop_vision_frame)
238
+ output_crop_vision_frame = obscure_frame(output_crop_vision_frame)
239
+ return numpy.hstack((target_crop_vision_frame, output_crop_vision_frame))
240
+
241
+ temp_vision_frame = obscure_frame(temp_vision_frame)
242
+ return temp_vision_frame
243
+
244
+ for processor_module in get_processors_modules(state_manager.get_item('processors')):
245
+ logger.disable()
246
+ if processor_module.pre_process('preview'):
247
+ logger.enable()
248
+ temp_vision_frame, temp_vision_mask = processor_module.process_frame(
249
+ {
250
+ 'reference_vision_frame': reference_vision_frame,
251
+ 'source_audio_frame': source_audio_frame,
252
+ 'source_voice_frame': source_voice_frame,
253
+ 'source_vision_frames': source_vision_frames,
254
+ 'target_vision_frames': target_vision_frames,
255
+ 'temp_vision_frame': temp_vision_frame[:, :, :3],
256
+ 'temp_vision_mask': temp_vision_mask
257
+ })
258
+ logger.enable()
259
+
260
+ temp_vision_frame = prepare_output_frame(target_vision_frame, temp_vision_frame, temp_vision_mask)
261
+
262
+ if preview_mode == 'frame-by-frame':
263
+ return numpy.hstack((target_vision_frame, temp_vision_frame))
264
+
265
+ if preview_mode == 'face-by-face':
266
+ target_crop_vision_frame, output_crop_vision_frame = create_face_by_face(reference_vision_frame, source_vision_frames, target_vision_frame, temp_vision_frame)
267
+ return numpy.hstack((target_crop_vision_frame, output_crop_vision_frame))
268
+
269
+ return temp_vision_frame
270
+
271
+
272
+ def create_face_by_face(reference_vision_frame : VisionFrame, source_vision_frames : List[VisionFrame], target_vision_frame : VisionFrame, temp_vision_frame : VisionFrame) -> Tuple[VisionFrame, VisionFrame]:
273
+ target_faces = select_faces(reference_vision_frame[:, :, :3], source_vision_frames, [ target_vision_frame[:, :, :3] ])
274
+ target_face = get_one_face(target_faces)
275
+
276
+ if target_face:
277
+ target_crop_vision_frame = extract_crop_frame(target_vision_frame, target_face)
278
+ output_crop_vision_frame = extract_crop_frame(temp_vision_frame, target_face)
279
+
280
+ if is_vision_frame(target_crop_vision_frame) and is_vision_frame(output_crop_vision_frame):
281
+ target_crop_dimension = min(target_crop_vision_frame.shape[:2])
282
+ target_crop_vision_frame = fit_cover_frame(target_crop_vision_frame, (target_crop_dimension, target_crop_dimension))
283
+ output_crop_vision_frame = fit_cover_frame(output_crop_vision_frame, (target_crop_dimension, target_crop_dimension))
284
+ return target_crop_vision_frame, output_crop_vision_frame
285
+
286
+ empty_vision_frame = numpy.zeros((512, 512, 4), dtype = numpy.uint8)
287
+ return empty_vision_frame, empty_vision_frame
288
+
289
+
290
+ def extract_crop_frame(vision_frame : VisionFrame, face : Face) -> Optional[VisionFrame]:
291
+ start_x, start_y, end_x, end_y = map(int, face.bounding_box)
292
+ padding_x = int((end_x - start_x) * 0.25)
293
+ padding_y = int((end_y - start_y) * 0.25)
294
+ start_x = max(0, start_x - padding_x)
295
+ start_y = max(0, start_y - padding_y)
296
+ end_x = max(0, end_x + padding_x)
297
+ end_y = max(0, end_y + padding_y)
298
+ crop_vision_frame = vision_frame[start_y:end_y, start_x:end_x]
299
+ return crop_vision_frame
300
+
301
+
302
+ def prepare_output_frame(target_vision_frame : VisionFrame, temp_vision_frame : VisionFrame, temp_vision_mask : Mask) -> VisionFrame:
303
+ temp_vision_mask = temp_vision_mask.clip(state_manager.get_item('background_remover_fill_color')[-1], 255)
304
+ temp_vision_frame = merge_vision_mask(temp_vision_frame, temp_vision_mask)
305
+ temp_vision_frame = cv2.resize(temp_vision_frame, target_vision_frame.shape[1::-1])
306
+ return temp_vision_frame
uis/components/preview_options.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.filesystem import is_video
7
+ from facefusion.uis import choices as uis_choices
8
+ from facefusion.uis.core import get_ui_components, register_ui_component
9
+ from facefusion.uis.types import ComponentOptions
10
+ from facefusion.vision import count_video_frame_total
11
+
12
+ PREVIEW_FRAME_SLIDER: Optional[gradio.Slider] = None
13
+ PREVIEW_MODE_DROPDOWN: Optional[gradio.Dropdown] = None
14
+ PREVIEW_RESOLUTION_DROPDOWN: Optional[gradio.Dropdown] = None
15
+
16
+
17
+ def render() -> None:
18
+ global PREVIEW_FRAME_SLIDER, PREVIEW_MODE_DROPDOWN, PREVIEW_RESOLUTION_DROPDOWN
19
+
20
+ preview_frame_slider_options : ComponentOptions =\
21
+ {
22
+ 'label': translator.get('uis.preview_frame_slider'),
23
+ 'step': 1,
24
+ 'minimum': 0,
25
+ 'maximum': 100,
26
+ 'visible': False
27
+ }
28
+ if is_video(state_manager.get_item('target_path')):
29
+ video_frame_total = count_video_frame_total(state_manager.get_item('target_path'))
30
+ preview_frame_slider_options['value'] = state_manager.get_item('reference_frame_number')
31
+ preview_frame_slider_options['maximum'] = video_frame_total - 1
32
+ preview_frame_slider_options['visible'] = True
33
+ PREVIEW_FRAME_SLIDER = gradio.Slider(**preview_frame_slider_options)
34
+ with gradio.Row():
35
+ PREVIEW_MODE_DROPDOWN = gradio.Dropdown(
36
+ label = translator.get('uis.preview_mode_dropdown'),
37
+ value = uis_choices.preview_modes[0],
38
+ choices = uis_choices.preview_modes,
39
+ visible = True
40
+ )
41
+ PREVIEW_RESOLUTION_DROPDOWN = gradio.Dropdown(
42
+ label = translator.get('uis.preview_resolution_dropdown'),
43
+ value = uis_choices.preview_resolutions[-1],
44
+ choices = uis_choices.preview_resolutions,
45
+ visible = True
46
+ )
47
+ register_ui_component('preview_mode_dropdown', PREVIEW_MODE_DROPDOWN)
48
+ register_ui_component('preview_resolution_dropdown', PREVIEW_RESOLUTION_DROPDOWN)
49
+ register_ui_component('preview_frame_slider', PREVIEW_FRAME_SLIDER)
50
+
51
+
52
+ def listen() -> None:
53
+ for ui_component in get_ui_components([ 'target_image', 'target_video' ]):
54
+ for method in [ 'change', 'clear' ]:
55
+ getattr(ui_component, method)(update_preview_frame_slider, outputs = PREVIEW_FRAME_SLIDER)
56
+
57
+
58
+ def update_preview_frame_slider() -> gradio.Slider:
59
+ if is_video(state_manager.get_item('target_path')):
60
+ video_frame_total = count_video_frame_total(state_manager.get_item('target_path'))
61
+ return gradio.Slider(maximum = video_frame_total - 1, visible = True)
62
+ return gradio.Slider(value = 0, visible = False)
uis/components/processors.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.filesystem import get_file_name, resolve_file_paths
7
+ from facefusion.processors.core import get_processors_modules
8
+ from facefusion.uis.core import register_ui_component
9
+
10
+ PROCESSORS_CHECKBOX_GROUP : Optional[gradio.CheckboxGroup] = None
11
+
12
+
13
+ def render() -> None:
14
+ global PROCESSORS_CHECKBOX_GROUP
15
+
16
+ PROCESSORS_CHECKBOX_GROUP = gradio.CheckboxGroup(
17
+ label = translator.get('uis.processors_checkbox_group'),
18
+ choices = sort_processors(state_manager.get_item('processors')),
19
+ value = state_manager.get_item('processors')
20
+ )
21
+ register_ui_component('processors_checkbox_group', PROCESSORS_CHECKBOX_GROUP)
22
+
23
+
24
+ def listen() -> None:
25
+ PROCESSORS_CHECKBOX_GROUP.change(update_processors, inputs = PROCESSORS_CHECKBOX_GROUP, outputs = PROCESSORS_CHECKBOX_GROUP)
26
+
27
+
28
+ def update_processors(processors : List[str]) -> gradio.CheckboxGroup:
29
+ for processor_module in get_processors_modules(state_manager.get_item('processors')):
30
+ if hasattr(processor_module, 'clear_inference_pool'):
31
+ processor_module.clear_inference_pool()
32
+
33
+ for processor_module in get_processors_modules(processors):
34
+ if not processor_module.pre_check():
35
+ return gradio.CheckboxGroup()
36
+
37
+ state_manager.set_item('processors', processors)
38
+ return gradio.CheckboxGroup(value = state_manager.get_item('processors'), choices = sort_processors(state_manager.get_item('processors')))
39
+
40
+
41
+ def sort_processors(processors : List[str]) -> List[str]:
42
+ available_processors = [ get_file_name(file_path) for file_path in resolve_file_paths('facefusion/processors/modules') ]
43
+ current_processors = []
44
+
45
+ for processor in processors + available_processors:
46
+ if processor in available_processors and processor not in current_processors:
47
+ current_processors.append(processor)
48
+
49
+ return current_processors
uis/components/source.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.common_helper import get_first
7
+ from facefusion.filesystem import filter_audio_paths, filter_image_paths, has_audio, has_image
8
+ from facefusion.uis.core import register_ui_component
9
+ from facefusion.uis.types import File
10
+
11
+ SOURCE_FILE : Optional[gradio.File] = None
12
+ SOURCE_AUDIO : Optional[gradio.Audio] = None
13
+ SOURCE_IMAGE : Optional[gradio.Image] = None
14
+
15
+
16
+ def render() -> None:
17
+ global SOURCE_FILE
18
+ global SOURCE_AUDIO
19
+ global SOURCE_IMAGE
20
+
21
+ has_source_audio = has_audio(state_manager.get_item('source_paths'))
22
+ has_source_image = has_image(state_manager.get_item('source_paths'))
23
+ SOURCE_FILE = gradio.File(
24
+ label = translator.get('uis.source_file'),
25
+ file_count = 'multiple',
26
+ value = state_manager.get_item('source_paths') if has_source_audio or has_source_image else None
27
+ )
28
+ source_file_names = [ source_file_value.get('path') for source_file_value in SOURCE_FILE.value ] if SOURCE_FILE.value else None
29
+ source_audio_path = get_first(filter_audio_paths(source_file_names))
30
+ source_image_path = get_first(filter_image_paths(source_file_names))
31
+ SOURCE_AUDIO = gradio.Audio(
32
+ value = source_audio_path if has_source_audio else None,
33
+ visible = has_source_audio,
34
+ show_label = False
35
+ )
36
+ SOURCE_IMAGE = gradio.Image(
37
+ value = source_image_path if has_source_image else None,
38
+ visible = has_source_image,
39
+ show_label = False
40
+ )
41
+ register_ui_component('source_audio', SOURCE_AUDIO)
42
+ register_ui_component('source_image', SOURCE_IMAGE)
43
+
44
+
45
+ def listen() -> None:
46
+ SOURCE_FILE.change(update, inputs = SOURCE_FILE, outputs = [ SOURCE_AUDIO, SOURCE_IMAGE ])
47
+
48
+
49
+ def update(files : List[File]) -> Tuple[gradio.Audio, gradio.Image]:
50
+ file_names = [ file.name for file in files ] if files else None
51
+ has_source_audio = has_audio(file_names)
52
+ has_source_image = has_image(file_names)
53
+
54
+ if has_source_audio or has_source_image:
55
+ source_audio_path = get_first(filter_audio_paths(file_names))
56
+ source_image_path = get_first(filter_image_paths(file_names))
57
+ state_manager.set_item('source_paths', file_names)
58
+ return gradio.Audio(value = source_audio_path, visible = has_source_audio), gradio.Image(value = source_image_path, visible = has_source_image)
59
+
60
+ state_manager.clear_item('source_paths')
61
+ return gradio.Audio(value = None, visible = False), gradio.Image(value = None, visible = False)
uis/components/target.py ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional, Tuple
2
+
3
+ import gradio
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.face_store import clear_faces
7
+ from facefusion.filesystem import is_image, is_video
8
+ from facefusion.uis.core import register_ui_component
9
+ from facefusion.uis.types import ComponentOptions, File
10
+
11
+ TARGET_FILE : Optional[gradio.File] = None
12
+ TARGET_IMAGE : Optional[gradio.Image] = None
13
+ TARGET_VIDEO : Optional[gradio.Video] = None
14
+
15
+
16
+ def render() -> None:
17
+ global TARGET_FILE
18
+ global TARGET_IMAGE
19
+ global TARGET_VIDEO
20
+
21
+ is_target_image = is_image(state_manager.get_item('target_path'))
22
+ is_target_video = is_video(state_manager.get_item('target_path'))
23
+ TARGET_FILE = gradio.File(
24
+ label = translator.get('uis.target_file'),
25
+ value = state_manager.get_item('target_path') if is_target_image or is_target_video else None
26
+ )
27
+ target_image_options : ComponentOptions =\
28
+ {
29
+ 'show_label': False,
30
+ 'visible': False
31
+ }
32
+ target_video_options : ComponentOptions =\
33
+ {
34
+ 'show_label': False,
35
+ 'visible': False
36
+ }
37
+ if is_target_image:
38
+ target_image_options['value'] = TARGET_FILE.value.get('path')
39
+ target_image_options['visible'] = True
40
+ if is_target_video:
41
+ target_video_options['value'] = TARGET_FILE.value.get('path')
42
+ target_video_options['visible'] = True
43
+ TARGET_IMAGE = gradio.Image(**target_image_options)
44
+ TARGET_VIDEO = gradio.Video(**target_video_options)
45
+ register_ui_component('target_image', TARGET_IMAGE)
46
+ register_ui_component('target_video', TARGET_VIDEO)
47
+
48
+
49
+ def listen() -> None:
50
+ TARGET_FILE.change(update, inputs = TARGET_FILE, outputs = [ TARGET_IMAGE, TARGET_VIDEO ])
51
+
52
+
53
+ def update(file : File) -> Tuple[gradio.Image, gradio.Video]:
54
+ clear_faces()
55
+
56
+ if file and is_image(file.name):
57
+ state_manager.set_item('target_path', file.name)
58
+ return gradio.Image(value = file.name, visible = True), gradio.Video(value = None, visible = False)
59
+
60
+ if file and is_video(file.name):
61
+ state_manager.set_item('target_path', file.name)
62
+ return gradio.Image(value = None, visible = False), gradio.Video(value = file.name, visible = True)
63
+
64
+ state_manager.clear_item('target_path')
65
+ return gradio.Image(value = None, visible = False), gradio.Video(value = None, visible = False)
uis/components/temp_frame.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import state_manager, translator
7
+ from facefusion.filesystem import is_video
8
+ from facefusion.types import TempFrameFormat
9
+ from facefusion.uis.core import get_ui_component
10
+
11
+ TEMP_FRAME_FORMAT_DROPDOWN : Optional[gradio.Dropdown] = None
12
+
13
+
14
+ def render() -> None:
15
+ global TEMP_FRAME_FORMAT_DROPDOWN
16
+
17
+ TEMP_FRAME_FORMAT_DROPDOWN = gradio.Dropdown(
18
+ label = translator.get('uis.temp_frame_format_dropdown'),
19
+ choices = facefusion.choices.temp_frame_formats,
20
+ value = state_manager.get_item('temp_frame_format'),
21
+ visible = is_video(state_manager.get_item('target_path'))
22
+ )
23
+
24
+
25
+ def listen() -> None:
26
+ TEMP_FRAME_FORMAT_DROPDOWN.change(update_temp_frame_format, inputs = TEMP_FRAME_FORMAT_DROPDOWN)
27
+
28
+ target_video = get_ui_component('target_video')
29
+ if target_video:
30
+ for method in [ 'change', 'clear' ]:
31
+ getattr(target_video, method)(remote_update, outputs = TEMP_FRAME_FORMAT_DROPDOWN)
32
+
33
+
34
+ def remote_update() -> gradio.Dropdown:
35
+ if is_video(state_manager.get_item('target_path')):
36
+ return gradio.Dropdown(visible = True)
37
+ return gradio.Dropdown(visible = False)
38
+
39
+
40
+ def update_temp_frame_format(temp_frame_format : TempFrameFormat) -> None:
41
+ state_manager.set_item('temp_frame_format', temp_frame_format)
42
+
uis/components/terminal.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import logging
3
+ import math
4
+ import os
5
+ from typing import Optional
6
+
7
+ import gradio
8
+ from tqdm import tqdm
9
+
10
+ import facefusion.choices
11
+ from facefusion import logger, state_manager, translator
12
+ from facefusion.types import LogLevel
13
+
14
+ LOG_LEVEL_DROPDOWN : Optional[gradio.Dropdown] = None
15
+ TERMINAL_TEXTBOX : Optional[gradio.Textbox] = None
16
+ LOG_BUFFER = io.StringIO()
17
+ LOG_HANDLER = logging.StreamHandler(LOG_BUFFER)
18
+ TQDM_UPDATE = tqdm.update
19
+
20
+
21
+ def render() -> None:
22
+ global LOG_LEVEL_DROPDOWN
23
+ global TERMINAL_TEXTBOX
24
+
25
+ LOG_LEVEL_DROPDOWN = gradio.Dropdown(
26
+ label = translator.get('uis.log_level_dropdown'),
27
+ choices = facefusion.choices.log_levels,
28
+ value = state_manager.get_item('log_level')
29
+ )
30
+ TERMINAL_TEXTBOX = gradio.Textbox(
31
+ label = translator.get('uis.terminal_textbox'),
32
+ value = read_logs,
33
+ lines = 8,
34
+ max_lines = 8,
35
+ every = 0.5,
36
+ show_copy_button = True
37
+ )
38
+
39
+
40
+ def listen() -> None:
41
+ LOG_LEVEL_DROPDOWN.change(update_log_level, inputs = LOG_LEVEL_DROPDOWN)
42
+ logger.get_package_logger().addHandler(LOG_HANDLER)
43
+ tqdm.update = tqdm_update
44
+
45
+
46
+ def update_log_level(log_level : LogLevel) -> None:
47
+ state_manager.set_item('log_level', log_level)
48
+ logger.init(state_manager.get_item('log_level'))
49
+
50
+
51
+ def tqdm_update(self : tqdm, n : int = 1) -> None:
52
+ TQDM_UPDATE(self, n)
53
+ output = create_tqdm_output(self)
54
+
55
+ if output:
56
+ LOG_BUFFER.seek(0)
57
+ log_buffer = LOG_BUFFER.read()
58
+ lines = log_buffer.splitlines()
59
+ if lines and lines[-1].startswith(self.desc):
60
+ position = log_buffer.rfind(lines[-1])
61
+ LOG_BUFFER.seek(position)
62
+ else:
63
+ LOG_BUFFER.seek(0, os.SEEK_END)
64
+ LOG_BUFFER.write(output + os.linesep)
65
+ LOG_BUFFER.flush()
66
+
67
+
68
+ def create_tqdm_output(self : tqdm) -> Optional[str]:
69
+ if not self.disable and self.desc and self.total:
70
+ percentage = math.floor(self.n / self.total * 100)
71
+ return self.desc + translator.get('colon') + ' ' + str(percentage) + '% (' + str(self.n) + '/' + str(self.total) + ')'
72
+ if not self.disable and self.desc and self.unit:
73
+ return self.desc + translator.get('colon') + ' ' + str(self.n) + ' ' + self.unit
74
+ return None
75
+
76
+
77
+ def read_logs() -> str:
78
+ LOG_BUFFER.seek(0)
79
+ logs = LOG_BUFFER.read().strip()
80
+ return logs
uis/components/trim_frame.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional, Tuple
2
+
3
+ from gradio_rangeslider import RangeSlider
4
+
5
+ from facefusion import state_manager, translator
6
+ from facefusion.face_store import clear_faces
7
+ from facefusion.filesystem import is_video
8
+ from facefusion.uis.core import get_ui_components
9
+ from facefusion.uis.types import ComponentOptions
10
+ from facefusion.vision import count_video_frame_total
11
+
12
+ TRIM_FRAME_RANGE_SLIDER : Optional[RangeSlider] = None
13
+
14
+
15
+ def render() -> None:
16
+ global TRIM_FRAME_RANGE_SLIDER
17
+
18
+ trim_frame_range_slider_options : ComponentOptions =\
19
+ {
20
+ 'label': translator.get('uis.trim_frame_slider'),
21
+ 'minimum': 0,
22
+ 'step': 1,
23
+ 'visible': False
24
+ }
25
+ if is_video(state_manager.get_item('target_path')):
26
+ video_frame_total = count_video_frame_total(state_manager.get_item('target_path'))
27
+ trim_frame_start = state_manager.get_item('trim_frame_start') or 0
28
+ trim_frame_end = state_manager.get_item('trim_frame_end') or video_frame_total
29
+ trim_frame_range_slider_options['maximum'] = video_frame_total
30
+ trim_frame_range_slider_options['value'] = (trim_frame_start, trim_frame_end)
31
+ trim_frame_range_slider_options['visible'] = True
32
+ TRIM_FRAME_RANGE_SLIDER = RangeSlider(**trim_frame_range_slider_options)
33
+
34
+
35
+ def listen() -> None:
36
+ TRIM_FRAME_RANGE_SLIDER.release(update_trim_frame, inputs = TRIM_FRAME_RANGE_SLIDER)
37
+ for ui_component in get_ui_components(
38
+ [
39
+ 'target_image',
40
+ 'target_video'
41
+ ]):
42
+ for method in [ 'change', 'clear' ]:
43
+ getattr(ui_component, method)(remote_update, outputs = [ TRIM_FRAME_RANGE_SLIDER ])
44
+
45
+
46
+ def remote_update() -> RangeSlider:
47
+ if is_video(state_manager.get_item('target_path')):
48
+ video_frame_total = count_video_frame_total(state_manager.get_item('target_path'))
49
+ state_manager.clear_item('trim_frame_start')
50
+ state_manager.clear_item('trim_frame_end')
51
+ return RangeSlider(value = (0, video_frame_total), maximum = video_frame_total, visible = True)
52
+ return RangeSlider(visible = False)
53
+
54
+
55
+ def update_trim_frame(trim_frame : Tuple[float, float]) -> None:
56
+ clear_faces()
57
+ trim_frame_start, trim_frame_end = trim_frame
58
+ video_frame_total = count_video_frame_total(state_manager.get_item('target_path'))
59
+ trim_frame_start = int(trim_frame_start) if trim_frame_start > 0 else None
60
+ trim_frame_end = int(trim_frame_end) if trim_frame_end < video_frame_total else None
61
+ state_manager.set_item('trim_frame_start', trim_frame_start)
62
+ state_manager.set_item('trim_frame_end', trim_frame_end)
uis/components/ui_workflow.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion
6
+ from facefusion import state_manager, translator
7
+ from facefusion.uis.core import register_ui_component
8
+
9
+ UI_WORKFLOW_DROPDOWN : Optional[gradio.Dropdown] = None
10
+
11
+
12
+ def render() -> None:
13
+ global UI_WORKFLOW_DROPDOWN
14
+
15
+ UI_WORKFLOW_DROPDOWN = gradio.Dropdown(
16
+ label = translator.get('uis.ui_workflow'),
17
+ choices = facefusion.choices.ui_workflows,
18
+ value = state_manager.get_item('ui_workflow'),
19
+ interactive = True
20
+ )
21
+ register_ui_component('ui_workflow_dropdown', UI_WORKFLOW_DROPDOWN)
uis/components/voice_extractor.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import List, Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import state_manager, translator, voice_extractor
7
+ from facefusion.filesystem import is_video
8
+ from facefusion.types import VoiceExtractorModel
9
+ from facefusion.uis.core import get_ui_component, get_ui_components, register_ui_component
10
+
11
+ VOICE_EXTRACTOR_MODEL_DROPDOWN : Optional[gradio.Dropdown] = None
12
+
13
+
14
+ def render() -> None:
15
+ global VOICE_EXTRACTOR_MODEL_DROPDOWN
16
+
17
+ has_lip_syncer = 'lip_syncer' in state_manager.get_item('processors')
18
+ VOICE_EXTRACTOR_MODEL_DROPDOWN = gradio.Dropdown(
19
+ label = translator.get('uis.voice_extractor_model_dropdown'),
20
+ choices = facefusion.choices.voice_extractor_models,
21
+ value = state_manager.get_item('voice_extractor_model'),
22
+ visible = is_video(state_manager.get_item('target_path')) and has_lip_syncer
23
+ )
24
+ register_ui_component('voice_extractor_model_dropdown', VOICE_EXTRACTOR_MODEL_DROPDOWN)
25
+
26
+
27
+ def listen() -> None:
28
+ VOICE_EXTRACTOR_MODEL_DROPDOWN.change(update_voice_extractor_model, inputs = VOICE_EXTRACTOR_MODEL_DROPDOWN, outputs = VOICE_EXTRACTOR_MODEL_DROPDOWN)
29
+
30
+ processors_checkbox_group = get_ui_component('processors_checkbox_group')
31
+ if processors_checkbox_group:
32
+ processors_checkbox_group.change(remote_update, inputs = processors_checkbox_group, outputs = VOICE_EXTRACTOR_MODEL_DROPDOWN)
33
+
34
+ for ui_component in get_ui_components(
35
+ [
36
+ 'target_image',
37
+ 'target_video'
38
+ ]):
39
+ for method in [ 'change', 'clear' ]:
40
+ getattr(ui_component, method)(remote_update, inputs = processors_checkbox_group, outputs = VOICE_EXTRACTOR_MODEL_DROPDOWN)
41
+
42
+
43
+ def remote_update(processors : List[str]) -> gradio.Dropdown:
44
+ has_lip_syncer = 'lip_syncer' in processors
45
+ if is_video(state_manager.get_item('target_path')) and has_lip_syncer:
46
+ return gradio.Dropdown(visible = True)
47
+ return gradio.Dropdown(visible = False)
48
+
49
+
50
+ def update_voice_extractor_model(voice_extractor_model : VoiceExtractorModel) -> gradio.Dropdown:
51
+ voice_extractor.clear_inference_pool()
52
+ state_manager.set_item('voice_extractor_model', voice_extractor_model)
53
+
54
+ if voice_extractor.pre_check():
55
+ gradio.Dropdown(value = state_manager.get_item('voice_extractor_model'))
56
+ return gradio.Dropdown()
uis/components/webcam.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Iterator, List, Optional, Tuple
2
+
3
+ import cv2
4
+ import gradio
5
+
6
+ from facefusion import state_manager, translator
7
+ from facefusion.camera_manager import clear_camera_pool, get_local_camera_capture
8
+ from facefusion.filesystem import has_image
9
+ from facefusion.streamer import multi_process_capture, open_stream
10
+ from facefusion.types import Fps, VisionFrame, WebcamMode
11
+ from facefusion.uis.core import get_ui_component
12
+ from facefusion.uis.types import File
13
+ from facefusion.vision import fit_cover_frame, unpack_resolution
14
+
15
+ SOURCE_FILE : Optional[gradio.File] = None
16
+ WEBCAM_IMAGE : Optional[gradio.Image] = None
17
+ WEBCAM_START_BUTTON : Optional[gradio.Button] = None
18
+ WEBCAM_STOP_BUTTON : Optional[gradio.Button] = None
19
+
20
+
21
+ def render() -> None:
22
+ global SOURCE_FILE
23
+ global WEBCAM_IMAGE
24
+ global WEBCAM_START_BUTTON
25
+ global WEBCAM_STOP_BUTTON
26
+
27
+ has_source_image = has_image(state_manager.get_item('source_paths'))
28
+ SOURCE_FILE = gradio.File(
29
+ label = translator.get('uis.source_file'),
30
+ file_count = 'multiple',
31
+ value = state_manager.get_item('source_paths') if has_source_image else None
32
+ )
33
+ WEBCAM_IMAGE = gradio.Image(
34
+ label = translator.get('uis.webcam_image'),
35
+ format = 'jpeg',
36
+ visible = False
37
+ )
38
+ WEBCAM_START_BUTTON = gradio.Button(
39
+ value = translator.get('uis.start_button'),
40
+ variant = 'primary',
41
+ size = 'sm'
42
+ )
43
+ WEBCAM_STOP_BUTTON = gradio.Button(
44
+ value = translator.get('uis.stop_button'),
45
+ size = 'sm',
46
+ visible = False
47
+ )
48
+
49
+
50
+ def listen() -> None:
51
+ SOURCE_FILE.change(update_source, inputs = SOURCE_FILE, outputs = SOURCE_FILE)
52
+ webcam_device_id_dropdown = get_ui_component('webcam_device_id_dropdown')
53
+ webcam_mode_radio = get_ui_component('webcam_mode_radio')
54
+ webcam_resolution_dropdown = get_ui_component('webcam_resolution_dropdown')
55
+ webcam_fps_slider = get_ui_component('webcam_fps_slider')
56
+
57
+ if webcam_device_id_dropdown and webcam_mode_radio and webcam_resolution_dropdown and webcam_fps_slider:
58
+ WEBCAM_START_BUTTON.click(pre_start, outputs = [ SOURCE_FILE, WEBCAM_IMAGE, WEBCAM_START_BUTTON, WEBCAM_STOP_BUTTON ])
59
+ start_event = WEBCAM_START_BUTTON.click(start, inputs = [ webcam_device_id_dropdown, webcam_mode_radio, webcam_resolution_dropdown, webcam_fps_slider ], outputs = WEBCAM_IMAGE)
60
+ start_event.then(pre_stop)
61
+ WEBCAM_STOP_BUTTON.click(stop, cancels = start_event, outputs = WEBCAM_IMAGE)
62
+ WEBCAM_STOP_BUTTON.click(pre_stop, outputs = [ SOURCE_FILE, WEBCAM_IMAGE, WEBCAM_START_BUTTON, WEBCAM_STOP_BUTTON ])
63
+
64
+
65
+ def update_source(files : List[File]) -> gradio.File:
66
+ file_names = [ file.name for file in files ] if files else None
67
+ has_source_image = has_image(file_names)
68
+
69
+ if has_source_image:
70
+ state_manager.set_item('source_paths', file_names)
71
+ return gradio.File(value = file_names)
72
+
73
+ state_manager.clear_item('source_paths')
74
+ return gradio.File(value = None)
75
+
76
+
77
+ def pre_start() -> Tuple[gradio.File, gradio.Image, gradio.Button, gradio.Button]:
78
+ return gradio.File(visible = False), gradio.Image(visible = True), gradio.Button(visible = False), gradio.Button(visible = True)
79
+
80
+
81
+ def pre_stop() -> Tuple[gradio.File, gradio.Image, gradio.Button, gradio.Button]:
82
+ return gradio.File(visible = True), gradio.Image(visible = False), gradio.Button(visible = True), gradio.Button(visible = False)
83
+
84
+
85
+ def start(webcam_device_id : int, webcam_mode : WebcamMode, webcam_resolution : str, webcam_fps : Fps) -> Iterator[VisionFrame]:
86
+ state_manager.init_item('face_selector_mode', 'one')
87
+ state_manager.sync_state()
88
+
89
+ camera_capture = get_local_camera_capture(webcam_device_id)
90
+ stream = None
91
+
92
+ if webcam_mode in [ 'udp', 'v4l2' ]:
93
+ stream = open_stream(webcam_mode, webcam_resolution, webcam_fps) #type:ignore[arg-type]
94
+ webcam_width, webcam_height = unpack_resolution(webcam_resolution)
95
+
96
+ if camera_capture and camera_capture.isOpened():
97
+ camera_capture.set(cv2.CAP_PROP_FRAME_WIDTH, webcam_width)
98
+ camera_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, webcam_height)
99
+ camera_capture.set(cv2.CAP_PROP_FPS, webcam_fps)
100
+
101
+ for capture_vision_frame in multi_process_capture(camera_capture, webcam_fps):
102
+ capture_vision_frame = cv2.cvtColor(capture_vision_frame, cv2.COLOR_BGR2RGB)
103
+ capture_vision_frame = fit_cover_frame(capture_vision_frame, (webcam_width, webcam_height))
104
+
105
+ if webcam_mode == 'inline':
106
+ yield capture_vision_frame
107
+ if webcam_mode in [ 'udp', 'v4l2' ]:
108
+ try:
109
+ stream.stdin.write(capture_vision_frame.data)
110
+ except Exception:
111
+ pass
112
+
113
+
114
+ def stop() -> gradio.Image:
115
+ clear_camera_pool()
116
+ return gradio.Image(value = None)
uis/components/webcam_options.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ import gradio
4
+
5
+ from facefusion import translator
6
+ from facefusion.camera_manager import detect_local_camera_ids
7
+ from facefusion.common_helper import get_first
8
+ from facefusion.uis import choices as uis_choices
9
+ from facefusion.uis.core import register_ui_component
10
+
11
+ WEBCAM_DEVICE_ID_DROPDOWN : Optional[gradio.Dropdown] = None
12
+ WEBCAM_MODE_RADIO : Optional[gradio.Radio] = None
13
+ WEBCAM_RESOLUTION_DROPDOWN : Optional[gradio.Dropdown] = None
14
+ WEBCAM_FPS_SLIDER : Optional[gradio.Slider] = None
15
+
16
+
17
+ def render() -> None:
18
+ global WEBCAM_DEVICE_ID_DROPDOWN
19
+ global WEBCAM_MODE_RADIO
20
+ global WEBCAM_RESOLUTION_DROPDOWN
21
+ global WEBCAM_FPS_SLIDER
22
+
23
+ local_camera_ids = detect_local_camera_ids(0, 10) or [ 'none' ] #type:ignore[list-item]
24
+ WEBCAM_DEVICE_ID_DROPDOWN = gradio.Dropdown(
25
+ value = get_first(local_camera_ids),
26
+ label = translator.get('uis.webcam_device_id_dropdown'),
27
+ choices = local_camera_ids
28
+ )
29
+ WEBCAM_MODE_RADIO = gradio.Radio(
30
+ label = translator.get('uis.webcam_mode_radio'),
31
+ choices = uis_choices.webcam_modes,
32
+ value = uis_choices.webcam_modes[0]
33
+ )
34
+ WEBCAM_RESOLUTION_DROPDOWN = gradio.Dropdown(
35
+ label = translator.get('uis.webcam_resolution_dropdown'),
36
+ choices = uis_choices.webcam_resolutions,
37
+ value = uis_choices.webcam_resolutions[0]
38
+ )
39
+ WEBCAM_FPS_SLIDER = gradio.Slider(
40
+ label = translator.get('uis.webcam_fps_slider'),
41
+ value = 30,
42
+ step = 1,
43
+ minimum = 1,
44
+ maximum = 30
45
+ )
46
+ register_ui_component('webcam_device_id_dropdown', WEBCAM_DEVICE_ID_DROPDOWN)
47
+ register_ui_component('webcam_mode_radio', WEBCAM_MODE_RADIO)
48
+ register_ui_component('webcam_resolution_dropdown', WEBCAM_RESOLUTION_DROPDOWN)
49
+ register_ui_component('webcam_fps_slider', WEBCAM_FPS_SLIDER)
uis/components/workflow.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ import gradio
4
+
5
+ import facefusion.choices
6
+ from facefusion import state_manager, translator
7
+ from facefusion.types import WorkflowStrategy
8
+
9
+ WORKFLOW_STRATEGY_DROPDOWN : Optional[gradio.Dropdown] = None
10
+
11
+
12
+ def render() -> None:
13
+ global WORKFLOW_STRATEGY_DROPDOWN
14
+
15
+ WORKFLOW_STRATEGY_DROPDOWN = gradio.Dropdown(
16
+ label = translator.get('uis.workflow_strategy_dropdown'),
17
+ choices = facefusion.choices.workflow_strategies,
18
+ value = state_manager.get_item('workflow_strategy')
19
+ )
20
+
21
+
22
+ def listen() -> None:
23
+ WORKFLOW_STRATEGY_DROPDOWN.change(update_workflow_strategy, inputs = WORKFLOW_STRATEGY_DROPDOWN)
24
+
25
+
26
+ def update_workflow_strategy(workflow_strategy : WorkflowStrategy) -> None:
27
+ state_manager.set_item('workflow_strategy', workflow_strategy)