diff --git a/facefusion/core.py b/facefusion/core.py index e4aef22d..d0972961 100755 --- a/facefusion/core.py +++ b/facefusion/core.py @@ -16,6 +16,7 @@ from facefusion.processors.core import get_processors_modules from facefusion.program import create_program from facefusion.program_helper import validate_args from facefusion.types import Args, ErrorCode +from facefusion.vision import has_video_support from facefusion.workflows import image_to_image, image_to_video @@ -336,7 +337,8 @@ def conditional_process() -> ErrorCode: if is_image(state_manager.get_item('target_path')): return image_to_image.process(start_time) - if is_video(state_manager.get_item('target_path')): + + if is_video(state_manager.get_item('target_path')) and has_video_support(state_manager.get_item('target_path')): return image_to_video.process(start_time) return 0 diff --git a/facefusion/vision.py b/facefusion/vision.py index 561e374c..393b16e2 100644 --- a/facefusion/vision.py +++ b/facefusion/vision.py @@ -92,6 +92,15 @@ def read_video_frame(video_path : str, frame_number : int = 0) -> Optional[Visio return None +def has_video_support(video_path : str) -> bool: + video_frame_total = count_video_frame_total(video_path) + + if video_frame_total > 0: + return bool(numpy.any(read_video_frame(video_path, 1)) or numpy.any(read_video_frame(video_path, video_frame_total // 2)) or numpy.any(read_video_frame(video_path, video_frame_total))) + + return False + + def count_video_frame_total(video_path : str) -> int: if is_video(video_path): video_capture = get_video_capture(video_path) diff --git a/tests/test_vision.py b/tests/test_vision.py index 35bec382..91f9f76c 100644 --- a/tests/test_vision.py +++ b/tests/test_vision.py @@ -5,7 +5,7 @@ import pytest from facefusion.common_helper import is_linux from facefusion.download import conditional_download -from facefusion.vision import calculate_histogram_difference, count_trim_frame_total, count_video_frame_total, detect_image_resolution, detect_video_duration, detect_video_fps, detect_video_resolution, match_frame_color, normalize_resolution, pack_resolution, predict_video_frame_total, read_image, read_video_frame, restrict_image_resolution, restrict_trim_frame, restrict_video_fps, restrict_video_resolution, scale_resolution, unpack_resolution, write_image +from facefusion.vision import calculate_histogram_difference, count_trim_frame_total, count_video_frame_total, detect_image_resolution, detect_video_duration, detect_video_fps, detect_video_resolution, has_video_support, match_frame_color, normalize_resolution, pack_resolution, predict_video_frame_total, read_image, read_video_frame, restrict_image_resolution, restrict_trim_frame, restrict_video_fps, restrict_video_resolution, scale_resolution, unpack_resolution, write_image from .helper import get_test_example_file, get_test_examples_directory, get_test_output_file, prepare_test_output_directory @@ -28,6 +28,8 @@ def before_all() -> None: subprocess.run([ 'ffmpeg', '-i', get_test_example_file('target-240p.mp4'), '-vf', 'fps=60', get_test_example_file('target-240p-60fps.mp4') ]) subprocess.run([ 'ffmpeg', '-i', get_test_example_file('target-240p.mp4'), '-vf', 'transpose=0', get_test_example_file('target-240p-90deg.mp4') ]) subprocess.run([ 'ffmpeg', '-i', get_test_example_file('target-1080p.mp4'), '-vf', 'transpose=0', get_test_example_file('target-1080p-90deg.mp4') ]) + subprocess.run([ 'ffmpeg', '-i', get_test_example_file('target-240p.mp4'), '-frames:v', '1', get_test_example_file('target-240p-1frame.mp4') ]) + subprocess.run([ 'ffmpeg', '-i', get_test_example_file('target-240p.mp4'), '-frames:v', '2', get_test_example_file('target-240p-2frame.mp4') ]) @pytest.fixture(scope = 'function', autouse = True) @@ -67,6 +69,14 @@ def test_read_video_frame() -> None: assert read_video_frame('invalid') is None +@pytest.mark.skipif(os.environ.get('CI') and is_linux(), reason = 'h264 codec not present') +def test_has_video_support() -> None: + assert has_video_support(get_test_example_file('target-240p.mp4')) is True + assert has_video_support(get_test_example_file('target-240p-1frame.mp4')) is True + assert has_video_support(get_test_example_file('target-240p-2frame.mp4')) is True + assert has_video_support('invalid') is False + + def test_count_video_frame_total() -> None: assert count_video_frame_total(get_test_example_file('target-240p-25fps.mp4')) == 270 assert count_video_frame_total(get_test_example_file('target-240p-30fps.mp4')) == 324