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: