From 33cc6b40a4a538023e12893a0439ce5062e56e36 Mon Sep 17 00:00:00 2001 From: henryruhs Date: Wed, 5 Aug 2026 23:35:19 +0200 Subject: [PATCH 1/2] clean wording --- facefusion/locales.py | 3 --- tests/test_translator.py | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/facefusion/locales.py b/facefusion/locales.py index 90942f92..bcc982f2 100644 --- a/facefusion/locales.py +++ b/facefusion/locales.py @@ -4,7 +4,6 @@ LOCALES : Locales =\ { 'en': { - 'conda_not_activated': 'conda is not activated', 'python_not_supported': 'python version is not supported, upgrade to {version} or higher', 'dependency_not_installed': '{dependency} is not installed', 'creating_temp': 'creating temporary resources', @@ -96,8 +95,6 @@ LOCALES : Locales =\ 'exclamation_mark': '!', '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', 'temp_path': 'specify the directory for the temporary resources', 'jobs_path': 'specify the directory to store jobs', diff --git a/tests/test_translator.py b/tests/test_translator.py index 3773cb9e..909e966f 100644 --- a/tests/test_translator.py +++ b/tests/test_translator.py @@ -9,6 +9,6 @@ def test_load() -> None: def test_get() -> None: - assert translator.get('conda_not_activated') == 'conda is not activated' - assert translator.get('help.skip_conda') == 'skip the conda environment check' + assert translator.get('processing_stopped') == 'processing stopped' + assert translator.get('help.run') == 'run the program' assert translator.get('invalid') is None From 4b1dedb853e4838ca7f3cf70b572be241aee2497 Mon Sep 17 00:00:00 2001 From: Henry Ruhs Date: Mon, 10 Aug 2026 10:12:19 +0200 Subject: [PATCH 2/2] Patch 3.8.2 (#1219) * fix frame enhancer * adjust output_xxx_scale according to frame_enhancer_model * fix resolution issue * fix black screens under ffmpeg 9 --- facefusion/ffmpeg_builder.py | 2 +- facefusion/metadata.py | 2 +- facefusion/uis/components/output_options.py | 34 +++++++++++++++++++-- facefusion/workflows/to_video.py | 9 ++++-- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/facefusion/ffmpeg_builder.py b/facefusion/ffmpeg_builder.py index 57aca55d..78692cdb 100644 --- a/facefusion/ffmpeg_builder.py +++ b/facefusion/ffmpeg_builder.py @@ -118,7 +118,7 @@ def select_frame_range(frame_start : int, frame_end : int, video_fps : Fps) -> L def prevent_frame_drop() -> List[Command]: - return [ '-vsync', '0' ] + return [ '-fps_mode', 'passthrough' ] def restrict_color_transfer(color_transfer : ColorTransfer) -> List[Command]: diff --git a/facefusion/metadata.py b/facefusion/metadata.py index 24a1db62..fcc3c5ca 100644 --- a/facefusion/metadata.py +++ b/facefusion/metadata.py @@ -4,7 +4,7 @@ METADATA =\ { 'name': 'FaceFusion', 'description': 'Industry leading face manipulation platform', - 'version': '3.8.1', + 'version': '3.8.2', 'license': 'OpenRAIL-AS', 'author': 'Henry Ruhs', 'url': 'https://facefusion.io' diff --git a/facefusion/uis/components/output_options.py b/facefusion/uis/components/output_options.py index bad92bd4..e4e84d7a 100644 --- a/facefusion/uis/components/output_options.py +++ b/facefusion/uis/components/output_options.py @@ -1,4 +1,4 @@ -from typing import Optional, Tuple +from typing import List, Optional, Tuple 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.ffmpeg import get_available_encoder_set 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.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 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_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( [ '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) +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: state_manager.set_item('output_image_quality', int(output_image_quality)) diff --git a/facefusion/workflows/to_video.py b/facefusion/workflows/to_video.py index 3545bb43..ef02b0ba 100644 --- a/facefusion/workflows/to_video.py +++ b/facefusion/workflows/to_video.py @@ -90,7 +90,7 @@ def process_disk_frames() -> ErrorCode: 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_frame = get_middle(target_vision_frames) 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) + 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': 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) 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: 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() 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) while futures: