Compare commits

...
3 Commits
Author SHA1 Message Date
Henry RuhsandGitHub 8801668562 3.5.3
* honor webcam resolution to avoid stripe mismatch, update dependencies

* avoid version conflicts

* enforce prores video extraction to 8 bit

* make the installer more robust on execution switch

* make the installer more robust on execution switch

* improve the installer env handling

* different approach to handle env
2026-02-11 09:35:08 +01:00
Henry RuhsandGitHub a7f3de3dbc Rename local(s) to locale(s) (#1008) 2025-12-17 18:37:51 +01:00
Henry RuhsandGitHub 666c15f9da Patch 3.5.2 (#1002)
* Remove old files

* Fix some spacing

* Introduce retry to download

* More testing

* Better installer scripting (#994)

* Better installer scripting

* Add migraphx installer support

* Add migraphx installer support

* Ignore issue

* Ignore issue

* Make --force-install optional
2025-12-13 08:37:15 +01:00
30 changed files with 121 additions and 119 deletions
+2 -2
View File
@@ -43,9 +43,9 @@ def detect_local_camera_ids(id_start : int, id_end : int) -> List[int]:
local_camera_ids = [] local_camera_ids = []
for camera_id in range(id_start, id_end): for camera_id in range(id_start, id_end):
cv2.setLogLevel(0) cv2.utils.logging.setLogLevel(0)
camera_capture = get_local_camera_capture(camera_id) camera_capture = get_local_camera_capture(camera_id)
cv2.setLogLevel(3) cv2.utils.logging.setLogLevel(3)
if camera_capture and camera_capture.isOpened(): if camera_capture and camera_capture.isOpened():
local_camera_ids.append(camera_id) local_camera_ids.append(camera_id)
+5 -1
View File
@@ -16,7 +16,7 @@ def chain(*commands : List[Command]) -> List[Command]:
return list(itertools.chain(*commands)) return list(itertools.chain(*commands))
def head(url : str) -> List[Command]: def ping(url : str) -> List[Command]:
return [ '-I', url ] return [ '-I', url ]
@@ -26,3 +26,7 @@ def download(url : str, download_file_path : str) -> List[Command]:
def set_timeout(timeout : int) -> List[Command]: def set_timeout(timeout : int) -> List[Command]:
return [ '--connect-timeout', str(timeout) ] return [ '--connect-timeout', str(timeout) ]
def set_retry(retry : int) -> List[Command]:
return [ '--retry', str(retry) ]
+4 -3
View File
@@ -29,7 +29,8 @@ def conditional_download(download_directory_path : str, urls : List[str]) -> Non
with tqdm(total = download_size, initial = initial_size, desc = translator.get('downloading'), unit = 'B', unit_scale = True, unit_divisor = 1024, ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress: with tqdm(total = download_size, initial = initial_size, desc = translator.get('downloading'), unit = 'B', unit_scale = True, unit_divisor = 1024, ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
commands = curl_builder.chain( commands = curl_builder.chain(
curl_builder.download(url, download_file_path), curl_builder.download(url, download_file_path),
curl_builder.set_timeout(5) curl_builder.set_timeout(5),
curl_builder.set_retry(5)
) )
open_curl(commands) open_curl(commands)
current_size = initial_size current_size = initial_size
@@ -44,7 +45,7 @@ def conditional_download(download_directory_path : str, urls : List[str]) -> Non
@lru_cache(maxsize = 64) @lru_cache(maxsize = 64)
def get_static_download_size(url : str) -> int: def get_static_download_size(url : str) -> int:
commands = curl_builder.chain( commands = curl_builder.chain(
curl_builder.head(url), curl_builder.ping(url),
curl_builder.set_timeout(5) curl_builder.set_timeout(5)
) )
process = open_curl(commands) process = open_curl(commands)
@@ -62,7 +63,7 @@ def get_static_download_size(url : str) -> int:
@lru_cache(maxsize = 64) @lru_cache(maxsize = 64)
def ping_static_url(url : str) -> bool: def ping_static_url(url : str) -> bool:
commands = curl_builder.chain( commands = curl_builder.chain(
curl_builder.head(url), curl_builder.ping(url),
curl_builder.set_timeout(5) curl_builder.set_timeout(5)
) )
process = open_curl(commands) process = open_curl(commands)
+1
View File
@@ -114,6 +114,7 @@ def extract_frames(target_path : str, temp_video_resolution : Resolution, temp_v
ffmpeg_builder.set_input(target_path), ffmpeg_builder.set_input(target_path),
ffmpeg_builder.set_media_resolution(pack_resolution(temp_video_resolution)), ffmpeg_builder.set_media_resolution(pack_resolution(temp_video_resolution)),
ffmpeg_builder.set_frame_quality(0), ffmpeg_builder.set_frame_quality(0),
ffmpeg_builder.enforce_pixel_format('rgb24'),
ffmpeg_builder.select_frame_range(trim_frame_start, trim_frame_end, temp_video_fps), ffmpeg_builder.select_frame_range(trim_frame_start, trim_frame_end, temp_video_fps),
ffmpeg_builder.prevent_frame_drop(), ffmpeg_builder.prevent_frame_drop(),
ffmpeg_builder.set_output(temp_frames_pattern) ffmpeg_builder.set_output(temp_frames_pattern)
+4
View File
@@ -79,6 +79,10 @@ def unsafe_concat() -> List[Command]:
return [ '-f', 'concat', '-safe', '0' ] return [ '-f', 'concat', '-safe', '0' ]
def enforce_pixel_format(pixel_format : str) -> List[Command]:
return [ '-pix_fmt', pixel_format ]
def set_pixel_format(video_encoder : VideoEncoder) -> List[Command]: def set_pixel_format(video_encoder : VideoEncoder) -> List[Command]:
if video_encoder == 'rawvideo': if video_encoder == 'rawvideo':
return [ '-pix_fmt', 'rgb24' ] return [ '-pix_fmt', 'rgb24' ]
+32 -27
View File
@@ -10,30 +10,33 @@ from types import FrameType
from facefusion import metadata from facefusion import metadata
from facefusion.common_helper import is_linux, is_windows from facefusion.common_helper import is_linux, is_windows
LOCALS =\ LOCALES =\
{ {
'install_dependency': 'install the {dependency} package', 'install_dependency': 'install the {dependency} package',
'force_reinstall': 'force reinstall of packages',
'skip_conda': 'skip the conda environment check', 'skip_conda': 'skip the conda environment check',
'conda_not_activated': 'conda is not activated' 'conda_not_activated': 'conda is not activated'
} }
ONNXRUNTIME_SET =\ ONNXRUNTIME_SET =\
{ {
'default': ('onnxruntime', '1.23.2') 'default': ('onnxruntime', '1.24.1')
} }
if is_windows() or is_linux(): if is_windows() or is_linux():
ONNXRUNTIME_SET['cuda'] = ('onnxruntime-gpu', '1.23.2') ONNXRUNTIME_SET['cuda'] = ('onnxruntime-gpu', '1.24.1')
ONNXRUNTIME_SET['openvino'] = ('onnxruntime-openvino', '1.23.0') ONNXRUNTIME_SET['openvino'] = ('onnxruntime-openvino', '1.23.0')
if is_windows(): if is_windows():
ONNXRUNTIME_SET['directml'] = ('onnxruntime-directml', '1.23.0') ONNXRUNTIME_SET['directml'] = ('onnxruntime-directml', '1.24.1')
if is_linux(): if is_linux():
ONNXRUNTIME_SET['rocm'] = ('onnxruntime-rocm', '1.21.0') ONNXRUNTIME_SET['migraphx'] = ('onnxruntime-migraphx', '1.23.2')
ONNXRUNTIME_SET['rocm'] = ('onnxruntime-rocm', '1.22.2.post1')
def cli() -> None: def cli() -> None:
signal.signal(signal.SIGINT, signal_exit) signal.signal(signal.SIGINT, signal_exit)
program = ArgumentParser(formatter_class = partial(HelpFormatter, max_help_position = 50)) program = ArgumentParser(formatter_class = partial(HelpFormatter, max_help_position = 50))
program.add_argument('--onnxruntime', help = LOCALS.get('install_dependency').format(dependency = 'onnxruntime'), choices = ONNXRUNTIME_SET.keys(), required = True) program.add_argument('--onnxruntime', help = LOCALES.get('install_dependency').format(dependency = 'onnxruntime'), choices = ONNXRUNTIME_SET.keys(), required = True)
program.add_argument('--skip-conda', help = LOCALS.get('skip_conda'), action = 'store_true') program.add_argument('--force-reinstall', help = LOCALES.get('force_reinstall'), action = 'store_true')
program.add_argument('--skip-conda', help = LOCALES.get('skip_conda'), action = 'store_true')
program.add_argument('-v', '--version', version = metadata.get('name') + ' ' + metadata.get('version'), action = 'version') program.add_argument('-v', '--version', version = metadata.get('name') + ' ' + metadata.get('version'), action = 'version')
run(program) run(program)
@@ -45,56 +48,58 @@ def signal_exit(signum : int, frame : FrameType) -> None:
def run(program : ArgumentParser) -> None: def run(program : ArgumentParser) -> None:
args = program.parse_args() args = program.parse_args()
has_conda = 'CONDA_PREFIX' in os.environ has_conda = 'CONDA_PREFIX' in os.environ
onnxruntime_name, onnxruntime_version = ONNXRUNTIME_SET.get(args.onnxruntime)
if not args.skip_conda and not has_conda: if not args.skip_conda and not has_conda:
sys.stdout.write(LOCALS.get('conda_not_activated') + os.linesep) sys.stdout.write(LOCALES.get('conda_not_activated') + os.linesep)
sys.exit(1) sys.exit(1)
commands = [ shutil.which('pip'), 'install' ]
if args.force_reinstall:
commands.append('--force-reinstall')
with open('requirements.txt') as file: with open('requirements.txt') as file:
for line in file.readlines(): for line in file.readlines():
__line__ = line.strip() __line__ = line.strip()
if not __line__.startswith('onnxruntime'): if not __line__.startswith('onnxruntime'):
subprocess.call([ shutil.which('pip'), 'install', line, '--force-reinstall' ]) commands.append(__line__)
if args.onnxruntime == 'rocm': onnxruntime_name, onnxruntime_version = ONNXRUNTIME_SET.get(args.onnxruntime)
python_id = 'cp' + str(sys.version_info.major) + str(sys.version_info.minor) commands.append(onnxruntime_name + '==' + onnxruntime_version)
if python_id in [ 'cp310', 'cp312' ]: subprocess.call([shutil.which('pip'), 'uninstall', 'onnxruntime', onnxruntime_name, '-y', '-q' ])
wheel_name = 'onnxruntime_rocm-' + onnxruntime_version + '-' + python_id + '-' + python_id + '-linux_x86_64.whl'
wheel_url = 'https://repo.radeon.com/rocm/manylinux/rocm-rel-6.4/' + wheel_name subprocess.call(commands)
subprocess.call([ shutil.which('pip'), 'install', wheel_url, '--force-reinstall' ])
else:
subprocess.call([ shutil.which('pip'), 'install', onnxruntime_name + '==' + onnxruntime_version, '--force-reinstall' ])
if args.onnxruntime == 'cuda' and has_conda: if args.onnxruntime == 'cuda' and has_conda:
library_paths = [] library_paths = []
if is_linux(): if is_linux():
if os.getenv('LD_LIBRARY_PATH'):
library_paths = os.getenv('LD_LIBRARY_PATH').split(os.pathsep)
python_id = 'python' + str(sys.version_info.major) + '.' + str(sys.version_info.minor) python_id = 'python' + str(sys.version_info.major) + '.' + str(sys.version_info.minor)
library_paths.extend( library_paths.extend(
[ [
os.path.join(os.getenv('CONDA_PREFIX'), 'lib'), os.path.join(os.getenv('CONDA_PREFIX'), 'lib'),
os.path.join(os.getenv('CONDA_PREFIX'), 'lib', python_id, 'site-packages', 'tensorrt_libs') os.path.join(os.getenv('CONDA_PREFIX'), 'lib', python_id, 'site-packages', 'tensorrt_libs')
]) ])
library_paths = list(dict.fromkeys([ library_path for library_path in library_paths if os.path.exists(library_path) ]))
if os.getenv('LD_LIBRARY_PATH'):
library_paths.extend(os.getenv('LD_LIBRARY_PATH').split(os.pathsep))
library_paths = list(dict.fromkeys(filter(os.path.exists, library_paths)))
subprocess.call([ shutil.which('conda'), 'env', 'config', 'vars', 'set', 'LD_LIBRARY_PATH=' + os.pathsep.join(library_paths) ]) subprocess.call([ shutil.which('conda'), 'env', 'config', 'vars', 'set', 'LD_LIBRARY_PATH=' + os.pathsep.join(library_paths) ])
if is_windows(): if is_windows():
if os.getenv('PATH'):
library_paths = os.getenv('PATH').split(os.pathsep)
library_paths.extend( library_paths.extend(
[ [
os.path.join(os.getenv('CONDA_PREFIX'), 'Lib'), os.path.join(os.getenv('CONDA_PREFIX'), 'Lib'),
os.path.join(os.getenv('CONDA_PREFIX'), 'Lib', 'site-packages', 'tensorrt_libs') os.path.join(os.getenv('CONDA_PREFIX'), 'Lib', 'site-packages', 'tensorrt_libs')
]) ])
library_paths = list(dict.fromkeys([ library_path for library_path in library_paths if os.path.exists(library_path) ]))
if os.getenv('PATH'):
library_paths.extend(os.getenv('PATH').split(os.pathsep))
library_paths = list(dict.fromkeys(filter(os.path.exists, library_paths)))
subprocess.call([ shutil.which('conda'), 'env', 'config', 'vars', 'set', 'PATH=' + os.pathsep.join(library_paths) ]) subprocess.call([ shutil.which('conda'), 'env', 'config', 'vars', 'set', 'PATH=' + os.pathsep.join(library_paths) ])
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
@@ -189,7 +189,7 @@ LOCALS : Locals =\
}, },
'about': 'about':
{ {
'fund': 'fund training server', 'fund': 'fund ai workstation',
'subscribe': 'become a member', 'subscribe': 'become a member',
'join': 'join our community' 'join': 'join our community'
}, },
+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.5.1', 'version': '3.5.3',
'license': 'OpenRAIL-AS', 'license': 'OpenRAIL-AS',
'author': 'Henry Ruhs', 'author': 'Henry Ruhs',
'url': 'https://facefusion.io' 'url': 'https://facefusion.io'
-27
View File
@@ -1,27 +0,0 @@
from facefusion.processors.modules.age_modifier.choices import age_modifier_direction_range, age_modifier_models # noqa: F401
from facefusion.processors.modules.background_remover.choices import background_remover_color_range, background_remover_models # noqa: F401
from facefusion.processors.modules.deep_swapper.choices import deep_swapper_models, deep_swapper_morph_range # noqa: F401
from facefusion.processors.modules.expression_restorer.choices import expression_restorer_areas, expression_restorer_factor_range, expression_restorer_models # noqa: F401
from facefusion.processors.modules.face_debugger.choices import face_debugger_items # noqa: F401
from facefusion.processors.modules.face_editor.choices import ( # noqa: F401
face_editor_eye_gaze_horizontal_range,
face_editor_eye_gaze_vertical_range,
face_editor_eye_open_ratio_range,
face_editor_eyebrow_direction_range,
face_editor_head_pitch_range,
face_editor_head_roll_range,
face_editor_head_yaw_range,
face_editor_lip_open_ratio_range,
face_editor_models,
face_editor_mouth_grim_range,
face_editor_mouth_position_horizontal_range,
face_editor_mouth_position_vertical_range,
face_editor_mouth_pout_range,
face_editor_mouth_purse_range,
face_editor_mouth_smile_range,
)
from facefusion.processors.modules.face_enhancer.choices import face_enhancer_blend_range, face_enhancer_models, face_enhancer_weight_range # noqa: F401
from facefusion.processors.modules.face_swapper.choices import face_swapper_models, face_swapper_set, face_swapper_weight_range # noqa: F401
from facefusion.processors.modules.frame_colorizer.choices import frame_colorizer_blend_range, frame_colorizer_models, frame_colorizer_sizes # noqa: F401
from facefusion.processors.modules.frame_enhancer.choices import frame_enhancer_blend_range, frame_enhancer_models # noqa: F401
from facefusion.processors.modules.lip_syncer.choices import lip_syncer_models, lip_syncer_weight_range # noqa: F401
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
@@ -421,7 +421,7 @@ def register_args(program : ArgumentParser) -> None:
group_processors = find_argument_group(program, 'processors') group_processors = find_argument_group(program, 'processors')
if group_processors: if group_processors:
group_processors.add_argument('--background-remover-model', help = translator.get('help.model', __package__), default = config.get_str_value('processors', 'background_remover_model', 'rmbg_2.0'), choices = background_remover_choices.background_remover_models) group_processors.add_argument('--background-remover-model', help = translator.get('help.model', __package__), default = config.get_str_value('processors', 'background_remover_model', 'rmbg_2.0'), choices = background_remover_choices.background_remover_models)
group_processors.add_argument('--background-remover-color', help = translator.get('help.color', __package__), type = partial(sanitize_int_range, int_range = background_remover_choices.background_remover_color_range), default = config.get_int_list('processors', 'background_remover_color', '0 0 0 0'), nargs ='+') group_processors.add_argument('--background-remover-color', help = translator.get('help.color', __package__), type = partial(sanitize_int_range, int_range = background_remover_choices.background_remover_color_range), default = config.get_int_list('processors', 'background_remover_color', '0 0 0 0'), nargs = '+')
facefusion.jobs.job_store.register_step_keys([ 'background_remover_model', 'background_remover_color' ]) facefusion.jobs.job_store.register_step_keys([ 'background_remover_model', 'background_remover_color' ])
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
@@ -101,7 +101,7 @@ def register_args(program : ArgumentParser) -> None:
if group_processors: if group_processors:
group_processors.add_argument('--expression-restorer-model', help = translator.get('help.model', __package__), default = config.get_str_value('processors', 'expression_restorer_model', 'live_portrait'), choices = expression_restorer_choices.expression_restorer_models) group_processors.add_argument('--expression-restorer-model', help = translator.get('help.model', __package__), default = config.get_str_value('processors', 'expression_restorer_model', 'live_portrait'), choices = expression_restorer_choices.expression_restorer_models)
group_processors.add_argument('--expression-restorer-factor', help = translator.get('help.factor', __package__), type = int, default = config.get_int_value('processors', 'expression_restorer_factor', '80'), choices = expression_restorer_choices.expression_restorer_factor_range, metavar = create_int_metavar(expression_restorer_choices.expression_restorer_factor_range)) group_processors.add_argument('--expression-restorer-factor', help = translator.get('help.factor', __package__), type = int, default = config.get_int_value('processors', 'expression_restorer_factor', '80'), choices = expression_restorer_choices.expression_restorer_factor_range, metavar = create_int_metavar(expression_restorer_choices.expression_restorer_factor_range))
group_processors.add_argument('--expression-restorer-areas', help = translator.get('help.areas', __package__).format(choices = ', '.join(expression_restorer_choices.expression_restorer_areas)), default = config.get_str_list('processors', 'expression_restorer_areas', ' '.join(expression_restorer_choices.expression_restorer_areas)), choices = expression_restorer_choices.expression_restorer_areas, nargs ='+', metavar ='EXPRESSION_RESTORER_AREAS') group_processors.add_argument('--expression-restorer-areas', help = translator.get('help.areas', __package__).format(choices = ', '.join(expression_restorer_choices.expression_restorer_areas)), default = config.get_str_list('processors', 'expression_restorer_areas', ' '.join(expression_restorer_choices.expression_restorer_areas)), choices = expression_restorer_choices.expression_restorer_areas, nargs = '+', metavar = 'EXPRESSION_RESTORER_AREAS')
facefusion.jobs.job_store.register_step_keys([ 'expression_restorer_model', 'expression_restorer_factor', 'expression_restorer_areas' ]) facefusion.jobs.job_store.register_step_keys([ 'expression_restorer_model', 'expression_restorer_factor', 'expression_restorer_areas' ])
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
@@ -1,6 +1,6 @@
from facefusion.types import Locals from facefusion.types import Locales
LOCALS : Locals =\ LOCALES : Locales =\
{ {
'en': 'en':
{ {
-1
View File
@@ -269,7 +269,6 @@ def create_halt_on_error_program() -> ArgumentParser:
def create_job_id_program() -> ArgumentParser: def create_job_id_program() -> ArgumentParser:
program = ArgumentParser(add_help = False) program = ArgumentParser(add_help = False)
program.add_argument('job_id', help = translator.get('help.job_id')) program.add_argument('job_id', help = translator.get('help.job_id'))
job_store.register_job_keys([ 'job_id' ])
return program return program
+8 -8
View File
@@ -1,29 +1,29 @@
import importlib import importlib
from typing import Optional from typing import Optional
from facefusion.types import Language, LocalPoolSet, Locals from facefusion.types import Language, LocalePoolSet, Locales
LOCAL_POOL_SET : LocalPoolSet = {} LOCALE_POOL_SET : LocalePoolSet = {}
CURRENT_LANGUAGE : Language = 'en' CURRENT_LANGUAGE : Language = 'en'
def __autoload__(module_name : str) -> None: def __autoload__(module_name : str) -> None:
try: try:
__locals__ = importlib.import_module(module_name + '.locals') __locales__ = importlib.import_module(module_name + '.locales')
load(__locals__.LOCALS, module_name) load(__locales__.LOCALES, module_name)
except ImportError: except ImportError:
pass pass
def load(__locals__ : Locals, module_name : str) -> None: def load(__locales__ : Locales, module_name : str) -> None:
LOCAL_POOL_SET[module_name] = __locals__ LOCALE_POOL_SET[module_name] = __locales__
def get(notation : str, module_name : str = 'facefusion') -> Optional[str]: def get(notation : str, module_name : str = 'facefusion') -> Optional[str]:
if module_name not in LOCAL_POOL_SET: if module_name not in LOCALE_POOL_SET:
__autoload__(module_name) __autoload__(module_name)
current = LOCAL_POOL_SET.get(module_name).get(CURRENT_LANGUAGE) current = LOCALE_POOL_SET.get(module_name).get(CURRENT_LANGUAGE)
for fragment in notation.split('.'): for fragment in notation.split('.'):
if fragment in current: if fragment in current:
+2 -2
View File
@@ -51,8 +51,8 @@ FaceStore = TypedDict('FaceStore',
}) })
Language = Literal['en'] Language = Literal['en']
Locals : TypeAlias = Dict[Language, Dict[str, Any]] Locales : TypeAlias = Dict[Language, Dict[str, Any]]
LocalPoolSet : TypeAlias = Dict[str, Locals] LocalePoolSet : TypeAlias = Dict[str, Locales]
VideoCaptureSet : TypeAlias = Dict[str, cv2.VideoCapture] VideoCaptureSet : TypeAlias = Dict[str, cv2.VideoCapture]
VideoWriterSet : TypeAlias = Dict[str, cv2.VideoWriter] VideoWriterSet : TypeAlias = Dict[str, cv2.VideoWriter]
+3 -2
View File
@@ -10,7 +10,7 @@ from facefusion.streamer import multi_process_capture, open_stream
from facefusion.types import Fps, VisionFrame, WebcamMode from facefusion.types import Fps, VisionFrame, WebcamMode
from facefusion.uis.core import get_ui_component from facefusion.uis.core import get_ui_component
from facefusion.uis.types import File from facefusion.uis.types import File
from facefusion.vision import unpack_resolution from facefusion.vision import fit_cover_frame, unpack_resolution
SOURCE_FILE : Optional[gradio.File] = None SOURCE_FILE : Optional[gradio.File] = None
WEBCAM_IMAGE : Optional[gradio.Image] = None WEBCAM_IMAGE : Optional[gradio.Image] = None
@@ -100,10 +100,11 @@ def start(webcam_device_id : int, webcam_mode : WebcamMode, webcam_resolution :
for capture_frame in multi_process_capture(camera_capture, webcam_fps): for capture_frame in multi_process_capture(camera_capture, webcam_fps):
capture_frame = cv2.cvtColor(capture_frame, cv2.COLOR_BGR2RGB) capture_frame = cv2.cvtColor(capture_frame, cv2.COLOR_BGR2RGB)
capture_frame = fit_cover_frame(capture_frame, (webcam_width, webcam_height))
if webcam_mode == 'inline': if webcam_mode == 'inline':
yield capture_frame yield capture_frame
else: if webcam_mode in [ 'udp', 'v4l2' ]:
try: try:
stream.stdin.write(capture_frame.tobytes()) stream.stdin.write(capture_frame.tobytes())
except Exception: except Exception:
+6 -7
View File
@@ -1,9 +1,8 @@
gradio-rangeslider==0.0.8 gradio-rangeslider==0.0.8
gradio==5.44.1 gradio==5.44.1
numpy==2.3.4 numpy==2.2.1
onnx==1.19.1 onnx==1.20.1
onnxruntime==1.23.2 onnxruntime==1.24.1
opencv-python==4.12.0.88 opencv-python==4.13.0.92
psutil==7.1.2 tqdm==4.67.3
tqdm==4.67.1 scipy==1.17.0
scipy==1.16.3
+5 -2
View File
@@ -1,7 +1,7 @@
from shutil import which from shutil import which
from facefusion import metadata from facefusion import metadata
from facefusion.curl_builder import chain, head, run from facefusion.curl_builder import chain, ping, run, set_timeout
def test_run() -> None: def test_run() -> None:
@@ -11,4 +11,7 @@ def test_run() -> None:
def test_chain() -> None: def test_chain() -> None:
assert chain(head(metadata.get('url'))) == [ '-I', metadata.get('url') ] assert chain(
ping(metadata.get('url')),
set_timeout(5)
) == [ '-I', metadata.get('url'), '--connect-timeout', '5' ]
+18 -6
View File
@@ -1,8 +1,6 @@
from argparse import ArgumentParser from argparse import ArgumentParser
import pytest from facefusion.program_helper import find_argument_group, validate_actions, validate_args
from facefusion.program_helper import find_argument_group, validate_actions
def test_find_argument_group() -> None: def test_find_argument_group() -> None:
@@ -12,12 +10,26 @@ def test_find_argument_group() -> None:
assert find_argument_group(program, 'test-1') assert find_argument_group(program, 'test-1')
assert find_argument_group(program, 'test-2') assert find_argument_group(program, 'test-2')
assert find_argument_group(program, 'invalid') is None assert find_argument_group(program, 'test-3') is None
@pytest.mark.skip()
def test_validate_args() -> None: def test_validate_args() -> None:
pass program = ArgumentParser()
program.add_argument('--test-1', default = 'test_1', choices = [ 'test_1', 'test_2' ])
assert validate_args(program) is True
subparsers = program.add_subparsers()
sub_program = subparsers.add_parser('sub-command')
sub_program.add_argument('--test-2', default = 'test_2', choices = [ 'test_1', 'test_2' ])
assert validate_args(program) is True
for action in sub_program._actions:
if action.dest == 'test_2':
action.default = 'test_3'
assert validate_args(program) is False
def test_validate_actions() -> None: def test_validate_actions() -> None:
+3 -3
View File
@@ -1,11 +1,11 @@
from facefusion import translator from facefusion import translator
from facefusion.locals import LOCALS from facefusion.locales import LOCALES
def test_load() -> None: def test_load() -> None:
translator.load(LOCALS, __name__) translator.load(LOCALES, __name__)
assert __name__ in translator.LOCAL_POOL_SET assert __name__ in translator.LOCALE_POOL_SET
def test_get() -> None: def test_get() -> None: