andro1241 commited on
Commit
96ad92d
·
verified ·
1 Parent(s): 5c734f0

Upload 5 files

Browse files
Files changed (5) hide show
  1. uis/choices.py +23 -0
  2. uis/core.py +200 -0
  3. uis/overrides.py +31 -0
  4. uis/types.py +104 -0
  5. uis/ui_helper.py +26 -0
uis/choices.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict, List
2
+
3
+ from facefusion.types import Color, WebcamMode
4
+ from facefusion.uis.types import JobManagerAction, JobRunnerAction, PreviewMode
5
+
6
+ job_manager_actions : List[JobManagerAction] = [ 'job-create', 'job-submit', 'job-delete', 'job-add-step', 'job-remix-step', 'job-insert-step', 'job-remove-step' ]
7
+ job_runner_actions : List[JobRunnerAction] = [ 'job-run', 'job-run-all', 'job-retry', 'job-retry-all' ]
8
+
9
+ preview_modes : List[PreviewMode] = [ 'default', 'frame-by-frame', 'face-by-face' ]
10
+ preview_resolutions : List[str] = [ '512x512', '768x768', '1024x1024' ]
11
+
12
+ webcam_modes : List[WebcamMode] = [ 'inline', 'udp', 'v4l2' ]
13
+ webcam_resolutions : List[str] = [ '320x240', '640x480', '800x600', '1024x768', '1280x720', '1280x960', '1920x1080' ]
14
+
15
+ background_remover_fill_colors : Dict[str, Color] =\
16
+ {
17
+ 'red' : (255, 0, 0, 255),
18
+ 'green' : (0, 255, 0, 255),
19
+ 'blue' : (0, 0, 255, 255),
20
+ 'black' : (0, 0, 0, 255),
21
+ 'white' : (255, 255, 255, 255),
22
+ 'alpha' : (0, 0, 0, 0)
23
+ }
uis/core.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import importlib
2
+ import logging
3
+ import os
4
+ import warnings
5
+ from types import ModuleType
6
+ from typing import Any, Dict, List, Optional
7
+
8
+ import gradio
9
+ from gradio.themes import Size
10
+
11
+ import facefusion.uis.overrides as uis_overrides
12
+ from facefusion import logger, metadata, state_manager, translator
13
+ from facefusion.exit_helper import hard_exit
14
+ from facefusion.filesystem import resolve_relative_path
15
+ from facefusion.uis.types import Component, ComponentName
16
+
17
+ UI_COMPONENTS: Dict[ComponentName, Component] = {}
18
+ UI_LAYOUT_MODULES : List[ModuleType] = []
19
+ UI_LAYOUT_METHODS =\
20
+ [
21
+ 'pre_check',
22
+ 'render',
23
+ 'listen',
24
+ 'run'
25
+ ]
26
+
27
+
28
+ def load_ui_layout_module(ui_layout : str) -> Any:
29
+ try:
30
+ ui_layout_module = importlib.import_module('facefusion.uis.layouts.' + ui_layout)
31
+ for method_name in UI_LAYOUT_METHODS:
32
+ if not hasattr(ui_layout_module, method_name):
33
+ raise NotImplementedError
34
+ except ModuleNotFoundError as exception:
35
+ logger.error(translator.get('ui_layout_not_loaded').format(ui_layout = ui_layout), __name__)
36
+ logger.debug(exception.msg, __name__)
37
+ hard_exit(1)
38
+ except NotImplementedError:
39
+ logger.error(translator.get('ui_layout_not_implemented').format(ui_layout = ui_layout), __name__)
40
+ hard_exit(1)
41
+ return ui_layout_module
42
+
43
+
44
+ def get_ui_layouts_modules(ui_layouts : List[str]) -> List[ModuleType]:
45
+ if not UI_LAYOUT_MODULES:
46
+ for ui_layout in ui_layouts:
47
+ ui_layout_module = load_ui_layout_module(ui_layout)
48
+ UI_LAYOUT_MODULES.append(ui_layout_module)
49
+ return UI_LAYOUT_MODULES
50
+
51
+
52
+ def get_ui_component(component_name : ComponentName) -> Optional[Component]:
53
+ if component_name in UI_COMPONENTS:
54
+ return UI_COMPONENTS[component_name]
55
+ return None
56
+
57
+
58
+ def get_ui_components(component_names : List[ComponentName]) -> Optional[List[Component]]:
59
+ ui_components = []
60
+
61
+ for component_name in component_names:
62
+ component = get_ui_component(component_name)
63
+ if component:
64
+ ui_components.append(component)
65
+ return ui_components
66
+
67
+
68
+ def register_ui_component(component_name : ComponentName, component: Component) -> None:
69
+ UI_COMPONENTS[component_name] = component
70
+
71
+
72
+ def init() -> None:
73
+ os.environ['GRADIO_ANALYTICS_ENABLED'] = '0'
74
+ os.environ['GRADIO_TEMP_DIR'] = os.path.join(state_manager.get_item('temp_path'), 'gradio')
75
+
76
+ logging.getLogger('asyncio').setLevel(logging.CRITICAL)
77
+ warnings.filterwarnings('ignore', category = UserWarning, module = 'gradio')
78
+ gradio.processing_utils._check_allowed = uis_overrides.mock
79
+ gradio.processing_utils.convert_video_to_playable_mp4 = uis_overrides.convert_video_to_playable_mp4
80
+ gradio.components.Number.raise_if_out_of_bounds = uis_overrides.mock
81
+
82
+
83
+ def launch() -> None:
84
+ ui_layouts_total = len(state_manager.get_item('ui_layouts'))
85
+ with gradio.Blocks(theme = get_theme(), css = get_css(), title = metadata.get('name') + ' ' + metadata.get('version'), fill_width = True) as ui:
86
+ for ui_layout in state_manager.get_item('ui_layouts'):
87
+ ui_layout_module = load_ui_layout_module(ui_layout)
88
+
89
+ if ui_layouts_total > 1:
90
+ with gradio.Tab(ui_layout):
91
+ ui_layout_module.render()
92
+ ui_layout_module.listen()
93
+ else:
94
+ ui_layout_module.render()
95
+ ui_layout_module.listen()
96
+
97
+ for ui_layout in state_manager.get_item('ui_layouts'):
98
+ ui_layout_module = load_ui_layout_module(ui_layout)
99
+ ui_layout_module.run(ui)
100
+
101
+
102
+ def get_theme() -> gradio.Theme:
103
+ return gradio.themes.Base(
104
+ primary_hue = gradio.themes.colors.red,
105
+ secondary_hue = gradio.themes.Color(
106
+ name = 'neutral',
107
+ c50 = '#fafafa',
108
+ c100 = '#f5f5f5',
109
+ c200 = '#e5e5e5',
110
+ c300 = '#d4d4d4',
111
+ c400 = '#a3a3a3',
112
+ c500 = '#737373',
113
+ c600 = '#525252',
114
+ c700 = '#404040',
115
+ c800 = '#262626',
116
+ c900 = '#212121',
117
+ c950 = '#171717',
118
+ ),
119
+ radius_size = Size(
120
+ xxs = '0.375rem',
121
+ xs = '0.375rem',
122
+ sm = '0.375rem',
123
+ md = '0.375rem',
124
+ lg = '0.375rem',
125
+ xl = '0.375rem',
126
+ xxl = '0.375rem',
127
+ ),
128
+ font = gradio.themes.GoogleFont('Open Sans')
129
+ ).set(
130
+ color_accent = 'transparent',
131
+ color_accent_soft = 'transparent',
132
+ color_accent_soft_dark = 'transparent',
133
+ background_fill_primary = '*neutral_100',
134
+ background_fill_primary_dark = '*neutral_950',
135
+ background_fill_secondary = '*neutral_50',
136
+ background_fill_secondary_dark = '*neutral_800',
137
+ block_background_fill = 'white',
138
+ block_background_fill_dark = '*neutral_900',
139
+ block_border_width = '0',
140
+ block_label_background_fill = '*neutral_100',
141
+ block_label_background_fill_dark = '*neutral_800',
142
+ block_label_border_width = 'none',
143
+ block_label_margin = '0.5rem',
144
+ block_label_radius = '*radius_md',
145
+ block_label_text_color = '*neutral_700',
146
+ block_label_text_size = '*text_sm',
147
+ block_label_text_color_dark = 'white',
148
+ block_label_text_weight = '600',
149
+ block_title_background_fill = '*neutral_100',
150
+ block_title_background_fill_dark = '*neutral_800',
151
+ block_title_padding = '*block_label_padding',
152
+ block_title_radius = '*block_label_radius',
153
+ block_title_text_color = '*neutral_700',
154
+ block_title_text_size = '*text_sm',
155
+ block_title_text_weight = '600',
156
+ block_padding = '0.5rem',
157
+ border_color_accent = 'transparent',
158
+ border_color_accent_dark = 'transparent',
159
+ border_color_accent_subdued = 'transparent',
160
+ border_color_accent_subdued_dark = 'transparent',
161
+ border_color_primary = 'transparent',
162
+ border_color_primary_dark = 'transparent',
163
+ button_large_padding = '2rem 0.5rem',
164
+ button_large_text_weight = 'normal',
165
+ button_primary_background_fill = '*primary_500',
166
+ button_primary_background_fill_dark = '*primary_600',
167
+ button_primary_text_color = 'white',
168
+ button_secondary_background_fill = 'white',
169
+ button_secondary_background_fill_dark = '*neutral_800',
170
+ button_secondary_background_fill_hover = 'white',
171
+ button_secondary_background_fill_hover_dark = '*neutral_800',
172
+ button_secondary_text_color = '*neutral_800',
173
+ button_small_padding = '0.75rem',
174
+ button_small_text_size = '0.875rem',
175
+ checkbox_background_color = '*neutral_200',
176
+ checkbox_background_color_dark = '*neutral_900',
177
+ checkbox_background_color_selected = '*primary_600',
178
+ checkbox_background_color_selected_dark = '*primary_700',
179
+ checkbox_label_background_fill = '*neutral_50',
180
+ checkbox_label_background_fill_dark = '*neutral_800',
181
+ checkbox_label_background_fill_hover = '*neutral_50',
182
+ checkbox_label_background_fill_hover_dark = '*neutral_800',
183
+ checkbox_label_background_fill_selected = '*primary_500',
184
+ checkbox_label_background_fill_selected_dark = '*primary_600',
185
+ checkbox_label_text_color_selected = 'white',
186
+ error_background_fill = 'white',
187
+ error_background_fill_dark = '*neutral_900',
188
+ error_text_color = '*primary_500',
189
+ error_text_color_dark = '*primary_600',
190
+ input_background_fill = '*neutral_50',
191
+ input_background_fill_dark = '*neutral_800',
192
+ shadow_drop = 'none',
193
+ slider_color = '*primary_500',
194
+ slider_color_dark = '*primary_600'
195
+ )
196
+
197
+
198
+ def get_css() -> str:
199
+ overrides_css_path = resolve_relative_path('uis/assets/overrides.css')
200
+ return open(overrides_css_path).read()
uis/overrides.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from facefusion import ffmpeg_builder
2
+ from facefusion.ffmpeg import run_ffmpeg
3
+ from facefusion.filesystem import get_file_size
4
+ from facefusion.temp_helper import create_temp_directory, get_temp_file_path
5
+ from facefusion.uis.types import MockArgs
6
+
7
+
8
+ def convert_video_to_playable_mp4(video_path : str) -> str:
9
+ video_file_size = get_file_size(video_path)
10
+ max_file_size = 512 * 1024 * 1024
11
+
12
+ create_temp_directory(video_path)
13
+ temp_video_path = get_temp_file_path(video_path)
14
+ commands = ffmpeg_builder.set_input(video_path)
15
+
16
+ if video_file_size > max_file_size:
17
+ commands.extend(ffmpeg_builder.set_video_duration(10))
18
+
19
+ commands.extend(ffmpeg_builder.force_output(temp_video_path))
20
+
21
+ process = run_ffmpeg(commands)
22
+ process.communicate()
23
+
24
+ if process.returncode == 0:
25
+ return temp_video_path
26
+
27
+ return video_path
28
+
29
+
30
+ def mock(*args : MockArgs, **kwargs : MockArgs) -> None:
31
+ pass
uis/types.py ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Dict, IO, Literal, TypeAlias
2
+
3
+ File : TypeAlias = IO[Any]
4
+ ComponentName = Literal\
5
+ [
6
+ 'age_modifier_direction_slider',
7
+ 'age_modifier_model_dropdown',
8
+ 'background_remover_model_dropdown',
9
+ 'background_remover_fill_color_red_number',
10
+ 'background_remover_fill_color_green_number',
11
+ 'background_remover_fill_color_blue_number',
12
+ 'background_remover_fill_color_alpha_number',
13
+ 'background_remover_despill_color_red_number',
14
+ 'background_remover_despill_color_green_number',
15
+ 'background_remover_despill_color_blue_number',
16
+ 'background_remover_despill_color_alpha_number',
17
+ 'deep_swapper_model_dropdown',
18
+ 'deep_swapper_morph_slider',
19
+ 'expression_restorer_factor_slider',
20
+ 'expression_restorer_model_dropdown',
21
+ 'expression_restorer_areas_checkbox_group',
22
+ 'face_debugger_items_checkbox_group',
23
+ 'face_detector_angles_checkbox_group',
24
+ 'face_detector_model_dropdown',
25
+ 'face_detector_margin_slider',
26
+ 'face_detector_score_slider',
27
+ 'face_detector_size_dropdown',
28
+ 'face_editor_eyebrow_direction_slider',
29
+ 'face_editor_eye_gaze_horizontal_slider',
30
+ 'face_editor_eye_gaze_vertical_slider',
31
+ 'face_editor_eye_open_ratio_slider',
32
+ 'face_editor_head_pitch_slider',
33
+ 'face_editor_head_roll_slider',
34
+ 'face_editor_head_yaw_slider',
35
+ 'face_editor_lip_open_ratio_slider',
36
+ 'face_editor_model_dropdown',
37
+ 'face_editor_mouth_grim_slider',
38
+ 'face_editor_mouth_position_horizontal_slider',
39
+ 'face_editor_mouth_position_vertical_slider',
40
+ 'face_editor_mouth_pout_slider',
41
+ 'face_editor_mouth_purse_slider',
42
+ 'face_editor_mouth_smile_slider',
43
+ 'face_enhancer_blend_slider',
44
+ 'face_enhancer_model_dropdown',
45
+ 'face_enhancer_weight_slider',
46
+ 'face_landmarker_model_dropdown',
47
+ 'face_landmarker_score_slider',
48
+ 'face_mask_types_checkbox_group',
49
+ 'face_mask_areas_checkbox_group',
50
+ 'face_mask_regions_checkbox_group',
51
+ 'face_mask_blur_slider',
52
+ 'face_mask_padding_bottom_slider',
53
+ 'face_mask_padding_left_slider',
54
+ 'face_mask_padding_right_slider',
55
+ 'face_mask_padding_top_slider',
56
+ 'face_selector_age_range_slider',
57
+ 'face_selector_gender_dropdown',
58
+ 'face_selector_mode_dropdown',
59
+ 'face_selector_order_dropdown',
60
+ 'face_selector_race_dropdown',
61
+ 'face_tracker_score_slider',
62
+ 'face_swapper_model_dropdown',
63
+ 'face_swapper_pixel_boost_dropdown',
64
+ 'face_swapper_weight_slider',
65
+ 'face_occluder_model_dropdown',
66
+ 'face_parser_model_dropdown',
67
+ 'voice_extractor_model_dropdown',
68
+ 'frame_colorizer_blend_slider',
69
+ 'frame_colorizer_model_dropdown',
70
+ 'frame_colorizer_size_dropdown',
71
+ 'frame_enhancer_blend_slider',
72
+ 'frame_enhancer_model_dropdown',
73
+ 'job_list_job_status_checkbox_group',
74
+ 'lip_syncer_model_dropdown',
75
+ 'lip_syncer_weight_slider',
76
+ 'output_image',
77
+ 'output_video',
78
+ 'output_video_fps_slider',
79
+ 'preview_image',
80
+ 'preview_frame_slider',
81
+ 'preview_mode_dropdown',
82
+ 'preview_resolution_dropdown',
83
+ 'processors_checkbox_group',
84
+ 'reference_face_distance_slider',
85
+ 'reference_face_position_gallery',
86
+ 'source_audio',
87
+ 'source_image',
88
+ 'target_image',
89
+ 'target_video',
90
+ 'ui_workflow_dropdown',
91
+ 'webcam_device_id_dropdown',
92
+ 'webcam_fps_slider',
93
+ 'webcam_mode_radio',
94
+ 'webcam_resolution_dropdown'
95
+ ]
96
+ Component : TypeAlias = Any
97
+ ComponentOptions : TypeAlias = Dict[str, Any]
98
+
99
+ JobManagerAction = Literal['job-create', 'job-submit', 'job-delete', 'job-add-step', 'job-remix-step', 'job-insert-step', 'job-remove-step']
100
+ JobRunnerAction = Literal['job-run', 'job-run-all', 'job-retry', 'job-retry-all']
101
+
102
+ PreviewMode = Literal[ 'default', 'frame-by-frame', 'face-by-face' ]
103
+
104
+ MockArgs : TypeAlias = Any
uis/ui_helper.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import hashlib
2
+ import os
3
+ from typing import Optional
4
+
5
+ from facefusion import state_manager
6
+ from facefusion.filesystem import get_file_extension, is_image, is_video
7
+
8
+
9
+ def convert_int_none(value : int) -> Optional[int]:
10
+ if value == 'none':
11
+ return None
12
+ return value
13
+
14
+
15
+ def convert_str_none(value : str) -> Optional[str]:
16
+ if value == 'none':
17
+ return None
18
+ return value
19
+
20
+
21
+ def suggest_output_path(output_directory_path : str, target_path : str) -> Optional[str]:
22
+ if is_image(target_path) or is_video(target_path):
23
+ output_file_name = hashlib.sha1(str(state_manager.get_state()).encode()).hexdigest()[:8]
24
+ target_file_extension = get_file_extension(target_path)
25
+ return os.path.join(output_directory_path, output_file_name + target_file_extension)
26
+ return None