Compare commits

..
4 Commits
Author SHA1 Message Date
henryruhs 3e06b89db1 fix resolution issue 2026-08-08 16:36:51 +02:00
henryruhs 1d4cb9be82 adjust output_xxx_scale according to frame_enhancer_model 2026-08-08 15:38:54 +02:00
henryruhs 67e0a5835f fix frame enhancer 2026-08-07 15:41:51 +02:00
henryruhs 33cc6b40a4 clean wording 2026-08-05 23:35:19 +02:00
5 changed files with 41 additions and 11 deletions
-3
View File
@@ -4,7 +4,6 @@ LOCALES : Locales =\
{ {
'en': 'en':
{ {
'conda_not_activated': 'conda is not activated',
'python_not_supported': 'python version is not supported, upgrade to {version} or higher', 'python_not_supported': 'python version is not supported, upgrade to {version} or higher',
'dependency_not_installed': '{dependency} is not installed', 'dependency_not_installed': '{dependency} is not installed',
'creating_temp': 'creating temporary resources', 'creating_temp': 'creating temporary resources',
@@ -96,8 +95,6 @@ LOCALES : Locales =\
'exclamation_mark': '!', 'exclamation_mark': '!',
'help': 'help':
{ {
'install_dependency': 'choose the variant of {dependency} to install',
'skip_conda': 'skip the conda environment check',
'config_path': 'choose the config file to override defaults', 'config_path': 'choose the config file to override defaults',
'temp_path': 'specify the directory for the temporary resources', 'temp_path': 'specify the directory for the temporary resources',
'jobs_path': 'specify the directory to store jobs', 'jobs_path': 'specify the directory to store jobs',
+1 -1
View File
@@ -4,7 +4,7 @@ METADATA =\
{ {
'name': 'FaceFusion', 'name': 'FaceFusion',
'description': 'Industry leading face manipulation platform', 'description': 'Industry leading face manipulation platform',
'version': '3.8.1', 'version': '3.8.2',
'license': 'OpenRAIL-AS', 'license': 'OpenRAIL-AS',
'author': 'Henry Ruhs', 'author': 'Henry Ruhs',
'url': 'https://facefusion.io' 'url': 'https://facefusion.io'
+32 -2
View File
@@ -1,4 +1,4 @@
from typing import Optional, Tuple from typing import List, Optional, Tuple
import gradio import gradio
@@ -7,8 +7,10 @@ from facefusion import state_manager, translator
from facefusion.common_helper import calculate_float_step, calculate_int_step from facefusion.common_helper import calculate_float_step, calculate_int_step
from facefusion.ffmpeg import get_available_encoder_set from facefusion.ffmpeg import get_available_encoder_set
from facefusion.filesystem import is_image, is_video from facefusion.filesystem import is_image, is_video
from facefusion.processors.modules.frame_enhancer.core import create_static_model_set
from facefusion.processors.modules.frame_enhancer.types import FrameEnhancerModel
from facefusion.types import AudioEncoder, Fps, Scale, VideoEncoder, VideoPreset from facefusion.types import AudioEncoder, Fps, Scale, VideoEncoder, VideoPreset
from facefusion.uis.core import get_ui_components, register_ui_component from facefusion.uis.core import get_ui_component, get_ui_components, register_ui_component
from facefusion.vision import detect_video_fps from facefusion.vision import detect_video_fps
OUTPUT_IMAGE_QUALITY_SLIDER : Optional[gradio.Slider] = None OUTPUT_IMAGE_QUALITY_SLIDER : Optional[gradio.Slider] = None
@@ -126,6 +128,14 @@ def listen() -> None:
OUTPUT_VIDEO_SCALE_SLIDER.release(update_output_video_scale, inputs = OUTPUT_VIDEO_SCALE_SLIDER) OUTPUT_VIDEO_SCALE_SLIDER.release(update_output_video_scale, inputs = OUTPUT_VIDEO_SCALE_SLIDER)
OUTPUT_VIDEO_FPS_SLIDER.release(update_output_video_fps, inputs = OUTPUT_VIDEO_FPS_SLIDER) OUTPUT_VIDEO_FPS_SLIDER.release(update_output_video_fps, inputs = OUTPUT_VIDEO_FPS_SLIDER)
frame_enhancer_model_dropdown = get_ui_component('frame_enhancer_model_dropdown')
if frame_enhancer_model_dropdown:
frame_enhancer_model_dropdown.change(update_output_scale_by_frame_enhancer_model, inputs = frame_enhancer_model_dropdown, outputs = [ OUTPUT_IMAGE_SCALE_SLIDER, OUTPUT_VIDEO_SCALE_SLIDER ])
processors_checkbox_group = get_ui_component('processors_checkbox_group')
if processors_checkbox_group:
processors_checkbox_group.change(update_output_scale_by_processors, inputs = processors_checkbox_group, outputs = [ OUTPUT_IMAGE_SCALE_SLIDER, OUTPUT_VIDEO_SCALE_SLIDER ])
for ui_component in get_ui_components( for ui_component in get_ui_components(
[ [
'target_image', 'target_image',
@@ -144,6 +154,26 @@ def remote_update() -> Tuple[gradio.Slider, gradio.Slider, gradio.Dropdown, grad
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) 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)
def update_output_scale_by_frame_enhancer_model(frame_enhancer_model : FrameEnhancerModel) -> Tuple[gradio.Slider, gradio.Slider]:
frame_enhancer_scale = create_static_model_set('full').get(frame_enhancer_model).get('scale')
state_manager.set_item('output_image_scale', frame_enhancer_scale)
state_manager.set_item('output_video_scale', frame_enhancer_scale)
return gradio.Slider(value = state_manager.get_item('output_image_scale')), gradio.Slider(value = state_manager.get_item('output_video_scale'))
def update_output_scale_by_processors(processors : List[str]) -> Tuple[gradio.Slider, gradio.Slider]:
if 'frame_enhancer' in processors:
frame_enhancer_model = state_manager.get_item('frame_enhancer_model')
frame_enhancer_scale = create_static_model_set('full').get(frame_enhancer_model).get('scale')
state_manager.set_item('output_image_scale', frame_enhancer_scale)
state_manager.set_item('output_video_scale', frame_enhancer_scale)
return gradio.Slider(value = state_manager.get_item('output_image_scale')), gradio.Slider(value = state_manager.get_item('output_video_scale'))
state_manager.set_item('output_image_scale', 1.0)
state_manager.set_item('output_video_scale', 1.0)
return gradio.Slider(value = state_manager.get_item('output_image_scale')), gradio.Slider(value = state_manager.get_item('output_video_scale'))
def update_output_image_quality(output_image_quality : float) -> None: def update_output_image_quality(output_image_quality : float) -> None:
state_manager.set_item('output_image_quality', int(output_image_quality)) state_manager.set_item('output_image_quality', int(output_image_quality))
+6 -3
View File
@@ -90,7 +90,7 @@ def process_disk_frames() -> ErrorCode:
return 0 return 0
def process_memory_frame(frame_number : int, temp_video_resolution : Resolution) -> VisionFrame: def process_memory_frame(frame_number : int, temp_video_resolution : Resolution, output_video_resolution : Resolution) -> VisionFrame:
target_vision_frames = select_video_frames(state_manager.get_item('target_path'), frame_number, state_manager.get_item('target_frame_amount')) target_vision_frames = select_video_frames(state_manager.get_item('target_path'), frame_number, state_manager.get_item('target_frame_amount'))
target_vision_frame = get_middle(target_vision_frames) target_vision_frame = get_middle(target_vision_frames)
temp_vision_frame = target_vision_frame.copy() temp_vision_frame = target_vision_frame.copy()
@@ -100,6 +100,9 @@ def process_memory_frame(frame_number : int, temp_video_resolution : Resolution)
temp_vision_frame = process_temp_frame(target_vision_frames, temp_vision_frame, frame_number) temp_vision_frame = process_temp_frame(target_vision_frames, temp_vision_frame, frame_number)
if not (temp_vision_frame.shape[1], temp_vision_frame.shape[0]) == output_video_resolution:
temp_vision_frame = cv2.resize(temp_vision_frame, output_video_resolution)
if state_manager.get_item('temp_pixel_format') == 'bgra': if state_manager.get_item('temp_pixel_format') == 'bgra':
temp_vision_frame = cv2.cvtColor(temp_vision_frame, cv2.COLOR_BGR2BGRA) temp_vision_frame = cv2.cvtColor(temp_vision_frame, cv2.COLOR_BGR2BGRA)
@@ -117,7 +120,7 @@ def process_memory_frames() -> ErrorCode:
temp_frame_range = range(trim_frame_start, trim_frame_end) temp_frame_range = range(trim_frame_start, trim_frame_end)
if temp_frame_range: if temp_frame_range:
video_writer = video_manager.get_writer(state_manager.get_item('target_path'), temp_video_fps, temp_video_resolution, output_video_resolution, state_manager.get_item('output_video_fps')) video_writer = video_manager.get_writer(state_manager.get_item('target_path'), temp_video_fps, output_video_resolution, output_video_resolution, state_manager.get_item('output_video_fps'))
with tqdm(total = len(temp_frame_range), desc = translator.get('processing'), unit = 'frame', ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress: with tqdm(total = len(temp_frame_range), desc = translator.get('processing'), unit = 'frame', ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
progress.set_postfix(execution_providers = state_manager.get_item('execution_providers')) progress.set_postfix(execution_providers = state_manager.get_item('execution_providers'))
@@ -128,7 +131,7 @@ def process_memory_frames() -> ErrorCode:
futures : Deque[Future[VisionFrame]] = deque() futures : Deque[Future[VisionFrame]] = deque()
for frame_number in temp_frame_range: for frame_number in temp_frame_range:
future = executor.submit(process_memory_frame, frame_number, temp_video_resolution) future = executor.submit(process_memory_frame, frame_number, temp_video_resolution, output_video_resolution)
futures.append(future) futures.append(future)
while futures: while futures:
+2 -2
View File
@@ -9,6 +9,6 @@ def test_load() -> None:
def test_get() -> None: def test_get() -> None:
assert translator.get('conda_not_activated') == 'conda is not activated' assert translator.get('processing_stopped') == 'processing stopped'
assert translator.get('help.skip_conda') == 'skip the conda environment check' assert translator.get('help.run') == 'run the program'
assert translator.get('invalid') is None assert translator.get('invalid') is None