diff --git a/facefusion/download.py b/facefusion/download.py index 95d7f3b6..83c550d0 100644 --- a/facefusion/download.py +++ b/facefusion/download.py @@ -14,7 +14,7 @@ from facefusion.choices import download_provider_set from facefusion.common_helper import is_macos from facefusion.filesystem import get_file_size, is_file, remove_file from facefusion.hash_helper import validate_hash -from facefusion.typing import DownloadSet +from facefusion.typing import DownloadProviderKey, DownloadSet if is_macos(): ssl._create_default_https_context = ssl._create_unverified_context @@ -130,5 +130,9 @@ def resolve_download_url(base_name : str, file_name : str) -> Optional[str]: for download_provider in download_provider_set: if download_provider in download_providers: - return download_provider_set.get(download_provider).format(base_name = base_name, file_name = file_name) + return resolve_download_url_by_provider(download_provider, base_name, file_name) return None + + +def resolve_download_url_by_provider(download_provider : DownloadProviderKey, base_name : str, file_name : str) -> Optional[str]: + return download_provider_set.get(download_provider).format(base_name = base_name, file_name = file_name) diff --git a/facefusion/processors/choices.py b/facefusion/processors/choices.py index a4146b2e..0957dded 100755 --- a/facefusion/processors/choices.py +++ b/facefusion/processors/choices.py @@ -4,7 +4,7 @@ from facefusion.common_helper import create_float_range, create_int_range from facefusion.processors.typing import AgeModifierModel, DeepSwapperModel, ExpressionRestorerModel, FaceDebuggerItem, FaceEditorModel, FaceEnhancerModel, FaceSwapperSet, FrameColorizerModel, FrameEnhancerModel, LipSyncerModel age_modifier_models : List[AgeModifierModel] = [ 'styleganex_age' ] -deep_swapper_models : List[DeepSwapperModel] = [ 'iperov/jackie_chan_224' ] +deep_swapper_models : List[DeepSwapperModel] = [ 'iperov/emma_watson_224', 'iperov/jackie_chan_224', 'iperov/keanu_reeves_320', 'iperov/sylvester_stallone_224', 'iperov/taylor_swift_224' ] expression_restorer_models : List[ExpressionRestorerModel] = [ 'live_portrait' ] face_debugger_items : List[FaceDebuggerItem] = [ 'bounding-box', 'face-landmark-5', 'face-landmark-5/68', 'face-landmark-68', 'face-landmark-68/5', 'face-mask', 'face-detector-score', 'face-landmarker-score', 'age', 'gender', 'race' ] face_editor_models : List[FaceEditorModel] = [ 'live_portrait' ] diff --git a/facefusion/processors/modules/deep_swapper.py b/facefusion/processors/modules/deep_swapper.py index 80cbc40b..b2f10961 100755 --- a/facefusion/processors/modules/deep_swapper.py +++ b/facefusion/processors/modules/deep_swapper.py @@ -8,7 +8,7 @@ import facefusion.jobs.job_manager import facefusion.jobs.job_store import facefusion.processors.core as processors from facefusion import config, content_analyser, face_classifier, face_detector, face_landmarker, face_masker, face_recognizer, inference_manager, logger, process_manager, state_manager, wording -from facefusion.download import conditional_download_hashes, conditional_download_sources +from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url_by_provider from facefusion.face_analyser import get_many_faces, get_one_face from facefusion.face_helper import paste_back, warp_face_for_deepfacelive from facefusion.face_masker import create_occlusion_mask, create_static_box_mask @@ -22,31 +22,121 @@ from facefusion.thread_helper import thread_semaphore from facefusion.typing import ApplyStateItem, Args, Face, InferencePool, Mask, ModelOptions, ModelSet, ProcessMode, QueuePayload, UpdateProgress, VisionFrame from facefusion.vision import conditional_match_frame_color, read_image, read_static_image, write_image -MODEL_SET : ModelSet =\ -{ - 'iperov/jackie_chan_224': + +def create_model_set() -> ModelSet: + return\ { - 'hashes': + 'iperov/emma_watson_224': { - 'deep_swapper': + 'hashes': { - 'url': 'https://huggingface.co/bluefoxcreation/DFM/resolve/main/Jackie_Chan.hash', - 'path': resolve_relative_path('../.assets/models/Jackie_Chan.hash') - } + 'deep_swapper': + { + 'url': resolve_download_url_by_provider('huggingface', 'deepfacelive-models-iperov', 'emma_watson_224.hash'), + 'path': resolve_relative_path('../.assets/models/emma_watson_224.hash') + } + }, + 'sources': + { + 'deep_swapper': + { + 'url': resolve_download_url_by_provider('huggingface', 'deepfacelive-models-iperov', 'emma_watson_224.dfm'), + 'path': resolve_relative_path('../.assets/models/emma_watson_224.dfm') + } + }, + 'size': (224, 224), + 'shift': (0.0, 0.0), + 'coverage': 2.2 }, - 'sources': + 'iperov/jackie_chan_224': { - 'deep_swapper': + 'hashes': { - 'url': 'https://github.com/iperov/DeepFaceLive/releases/download/JACKIE_CHAN/Jackie_Chan.dfm', - 'path': resolve_relative_path('../.assets/models/Jackie_Chan.dfm') - } + 'deep_swapper': + { + 'url': resolve_download_url_by_provider('huggingface', 'deepfacelive-models-iperov', 'jackie_chan_224.hash'), + 'path': resolve_relative_path('../.assets/models/jackie_chan_224.hash') + } + }, + 'sources': + { + 'deep_swapper': + { + 'url': resolve_download_url_by_provider('huggingface', 'deepfacelive-models-iperov', 'jackie_chan_224.dfm'), + 'path': resolve_relative_path('../.assets/models/jackie_chan_224.dfm') + } + }, + 'size': (224, 224), + 'shift': (0.0, 0.0), + 'coverage': 2.2 }, - 'size': (224, 224), - 'shift': (0.0, 0.0), - 'coverage': 2.2 + 'iperov/keanu_reeves_320': + { + 'hashes': + { + 'deep_swapper': + { + 'url': resolve_download_url_by_provider('huggingface', 'deepfacelive-models-iperov', 'keanu_reeves_320.hash'), + 'path': resolve_relative_path('../.assets/models/keanu_reeves_320.hash') + } + }, + 'sources': + { + 'deep_swapper': + { + 'url': resolve_download_url_by_provider('huggingface', 'deepfacelive-models-iperov', 'keanu_reeves_320.dfm'), + 'path': resolve_relative_path('../.assets/models/keanu_reeves_320.dfm') + } + }, + 'size': (320, 320), + 'shift': (0.0, 0.0), + 'coverage': 2.2 + }, + 'iperov/sylvester_stallone_224': + { + 'hashes': + { + 'deep_swapper': + { + 'url': resolve_download_url_by_provider('huggingface', 'deepfacelive-models-iperov', 'sylvester_stallone_224.hash'), + 'path': resolve_relative_path('../.assets/models/sylvester_stallone_224.hash') + } + }, + 'sources': + { + 'deep_swapper': + { + 'url': resolve_download_url_by_provider('huggingface', 'deepfacelive-models-iperov', 'sylvester_stallone_224.dfm'), + 'path': resolve_relative_path('../.assets/models/sylvester_stallone_224.dfm') + } + }, + 'size': (224, 224), + 'shift': (0.0, 0.0), + 'coverage': 2.2 + }, + 'iperov/taylor_swift_224': + { + 'hashes': + { + 'deep_swapper': + { + 'url': resolve_download_url_by_provider('huggingface', 'deepfacelive-models-iperov', 'taylor_swift_224.hash'), + 'path': resolve_relative_path('../.assets/models/taylor_swift_224.hash') + } + }, + 'sources': + { + 'deep_swapper': + { + 'url': resolve_download_url_by_provider('huggingface', 'deepfacelive-models-iperov', 'taylor_swift_224.dfm'), + 'path': resolve_relative_path('../.assets/models/taylor_swift_224.dfm') + } + }, + 'size': (224, 224), + 'shift': (0.0, 0.0), + 'coverage': 2.2 + } } -} def get_inference_pool() -> InferencePool: @@ -62,7 +152,7 @@ def clear_inference_pool() -> None: def get_model_options() -> ModelOptions: deep_swapper_model = state_manager.get_item('deep_swapper_model') - return MODEL_SET.get(deep_swapper_model) + return create_model_set().get(deep_swapper_model) def register_args(program : ArgumentParser) -> None: diff --git a/facefusion/processors/typing.py b/facefusion/processors/typing.py index a5900b98..2c0e894b 100644 --- a/facefusion/processors/typing.py +++ b/facefusion/processors/typing.py @@ -5,7 +5,7 @@ from numpy._typing import NDArray from facefusion.typing import AppContext, AudioFrame, Face, FaceSet, VisionFrame AgeModifierModel = Literal['styleganex_age'] -DeepSwapperModel = Literal['iperov/jackie_chan_224'] +DeepSwapperModel = Literal['iperov/emma_watson_224', 'iperov/jackie_chan_224', 'iperov/keanu_reeves_320', 'iperov/sylvester_stallone_224', 'iperov/taylor_swift_224'] ExpressionRestorerModel = Literal['live_portrait'] FaceDebuggerItem = Literal['bounding-box', 'face-landmark-5', 'face-landmark-5/68', 'face-landmark-68', 'face-landmark-68/5', 'face-mask', 'face-detector-score', 'face-landmarker-score', 'age', 'gender', 'race'] FaceEditorModel = Literal['live_portrait']