From 3c8ad63d2535d756a232b6dbb416b8aa8048d382 Mon Sep 17 00:00:00 2001 From: henryruhs Date: Thu, 1 Feb 2024 12:51:59 +0100 Subject: [PATCH] Add lip-syncer support to source component --- facefusion/filesystem.py | 6 +++++ facefusion/uis/components/source.py | 34 +++++++++++++++++++++-------- requirements.txt | 2 +- tests/test_filesystem.py | 8 ++++++- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/facefusion/filesystem.py b/facefusion/filesystem.py index 98e8b6b9..521227bc 100644 --- a/facefusion/filesystem.py +++ b/facefusion/filesystem.py @@ -68,6 +68,12 @@ def is_audio(audio_path : str) -> bool: return False +def are_audios(audio_paths : List[str]) -> bool: + if audio_paths: + return all(is_audio(audio_path) for audio_path in audio_paths) + return False + + def is_image(image_path : str) -> bool: if is_file(image_path): return filetype.helpers.is_image(image_path) diff --git a/facefusion/uis/components/source.py b/facefusion/uis/components/source.py index 2423193f..a02b3d24 100644 --- a/facefusion/uis/components/source.py +++ b/facefusion/uis/components/source.py @@ -1,35 +1,49 @@ -from typing import Optional, List +from typing import Optional, List, Tuple import gradio import facefusion.globals from facefusion import wording from facefusion.uis.typing import File -from facefusion.filesystem import are_images +from facefusion.common_helper import get_first_item +from facefusion.filesystem import are_audios, are_images, filter_audio_paths, filter_image_paths from facefusion.uis.core import register_ui_component SOURCE_FILE : Optional[gradio.File] = None +SOURCE_AUDIO : Optional[gradio.Audio] = None SOURCE_IMAGE : Optional[gradio.Image] = None def render() -> None: global SOURCE_FILE + global SOURCE_AUDIO global SOURCE_IMAGE + are_source_audios = are_audios(facefusion.globals.source_paths) are_source_images = are_images(facefusion.globals.source_paths) SOURCE_FILE = gradio.File( file_count = 'multiple', file_types = [ + '.mp3', + '.wav', '.png', '.jpg', '.webp' ], label = wording.get('uis.source_file'), - value = facefusion.globals.source_paths if are_source_images else None + value = facefusion.globals.source_paths if are_source_audios or are_source_images else None ) source_file_names = [ source_file_value['name'] for source_file_value in SOURCE_FILE.value ] if SOURCE_FILE.value else None + source_audio_path = get_first_item(filter_audio_paths(source_file_names)) + source_image_path = get_first_item(filter_image_paths(source_file_names)) + SOURCE_AUDIO = gradio.Audio( + value = source_audio_path if are_source_audios else None, + visible = are_source_audios, + show_label = False, + show_download_button = False + ) SOURCE_IMAGE = gradio.Image( - value = source_file_names[0] if are_source_images else None, + value = source_image_path if are_source_images else None, visible = are_source_images, show_label = False ) @@ -37,13 +51,15 @@ def render() -> None: def listen() -> None: - SOURCE_FILE.change(update, inputs = SOURCE_FILE, outputs = SOURCE_IMAGE) + SOURCE_FILE.change(update, inputs = SOURCE_FILE, outputs = [ SOURCE_AUDIO, SOURCE_IMAGE ]) -def update(files : List[File]) -> gradio.Image: +def update(files : List[File]) -> Tuple[gradio.Audio, gradio.Image]: file_names = [ file.name for file in files ] if files else None - if are_images(file_names): + if are_audios(file_names) or are_images(file_names): facefusion.globals.source_paths = file_names - return gradio.Image(value = file_names[0], visible = True) + audio_path = get_first_item(filter_audio_paths(facefusion.globals.source_paths)) + image_path = get_first_item(filter_image_paths(facefusion.globals.source_paths)) + return gradio.Audio(value = audio_path, visible = True), gradio.Image(value = image_path, visible = True) facefusion.globals.source_paths = None - return gradio.Image(value = None, visible = False) + return gradio.Audio(value = None, visible = False), gradio.Image(value = None, visible = False) diff --git a/requirements.txt b/requirements.txt index 9efb84d3..d919a320 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ gradio==3.50.2 numpy==1.26.2 onnx==1.15.0 onnxruntime==1.17.0 -opencv-python==4.8.1.78 +opencv-python==4.9.0.80 psutil==5.9.6 realesrgan==0.3.0 torch==2.1.2 diff --git a/tests/test_filesystem.py b/tests/test_filesystem.py index 8ddb34c6..4f1a26d0 100644 --- a/tests/test_filesystem.py +++ b/tests/test_filesystem.py @@ -1,7 +1,7 @@ import pytest from facefusion.download import conditional_download -from facefusion.filesystem import is_file, is_directory, is_audio, is_image, are_images, is_video, filter_audio_paths, filter_image_paths, list_directory +from facefusion.filesystem import is_file, is_directory, is_audio, are_audios, is_image, are_images, is_video, filter_audio_paths, filter_image_paths, list_directory @pytest.fixture(scope = 'module', autouse = True) @@ -32,6 +32,12 @@ def test_is_audio() -> None: assert is_audio('invalid') is False +def test_are_audios() -> None: + assert are_audios([ '.assets/examples/source.mp3' ]) is True + assert are_audios([ '.assets/examples/source.mp3', '.assets/examples/target-240p.mp4' ]) is False + assert are_audios([ 'invalid' ]) is False + + def test_is_image() -> None: assert is_image('.assets/examples/source.jpg') is True assert is_image('.assets/examples/target-240p.mp4') is False