From 94b0a4032e8a23446b266d3525f9b0f080970f17 Mon Sep 17 00:00:00 2001 From: henryruhs Date: Mon, 6 Apr 2026 18:06:42 +0200 Subject: [PATCH] fix stuck ffmpeg due multi thread lock --- facefusion/apis/asset_helper.py | 2 +- facefusion/ffmpeg.py | 9 +++++++-- facefusion/ffprobe.py | 4 ++-- tests/test_api_assets.py | 5 ----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/facefusion/apis/asset_helper.py b/facefusion/apis/asset_helper.py index 28a0e616..008e4e30 100644 --- a/facefusion/apis/asset_helper.py +++ b/facefusion/apis/asset_helper.py @@ -42,7 +42,7 @@ def detect_media_type_by_format(file_format : str) -> Optional[MediaType]: def validate_asset_files(upload_files : List[UploadFile]) -> bool: - available_encoder_set = ffmpeg.get_available_encoder_set() + available_encoder_set = ffmpeg.get_static_available_encoder_set() for upload_file in upload_files: file_format = get_file_format(upload_file.filename) diff --git a/facefusion/ffmpeg.py b/facefusion/ffmpeg.py index 5305260f..6c5bb9ab 100644 --- a/facefusion/ffmpeg.py +++ b/facefusion/ffmpeg.py @@ -1,7 +1,7 @@ import os import subprocess import tempfile -from functools import partial +from functools import lru_cache, partial from typing import List, Optional, cast from tqdm import tqdm @@ -129,6 +129,11 @@ def get_available_encoder_set() -> EncoderSet: return available_encoder_set +@lru_cache(maxsize = None) +def get_static_available_encoder_set() -> EncoderSet: + return get_available_encoder_set() + + def extract_frames(target_path : str, output_path : str, temp_video_resolution : Resolution, temp_video_fps : Fps, trim_frame_start : int, trim_frame_end : int) -> bool: extract_frame_total = predict_video_frame_total(target_path, temp_video_fps, trim_frame_start, trim_frame_end) temp_frames_pattern = get_temp_frames_pattern(state_manager.get_temp_path(), output_path, state_manager.get_item('temp_frame_format'), '%08d') @@ -339,7 +344,7 @@ def sanitize_image(media_chunk_reader : MediaChunkReader, asset_path : str) -> b def sanitize_video(media_chunk_reader : MediaChunkReader, asset_path : str, security_strategy : ApiSecurityStrategy) -> bool: if security_strategy == 'strict': - available_video_encoders = get_available_encoder_set().get('video') + available_video_encoders = get_static_available_encoder_set().get('video') commands = ffmpeg_builder.chain( ffmpeg_builder.set_input('pipe:0'), ffmpeg_builder.set_video_encoder(available_video_encoders[0]), diff --git a/facefusion/ffprobe.py b/facefusion/ffprobe.py index 699c8eae..f41805a1 100644 --- a/facefusion/ffprobe.py +++ b/facefusion/ffprobe.py @@ -37,14 +37,14 @@ def extract_audio_metadata(audio_path : str) -> AudioMetadata: duration = float(audio_entries.get('duration')) sample_rate = int(audio_entries.get('sample_rate')) frame_total = int(duration * sample_rate) - channnel_total = int(audio_entries.get('channels')) + channel_total = int(audio_entries.get('channels')) bit_rate = int(audio_entries.get('bit_rate')) audio_metadata : AudioMetadata =\ { 'duration' : duration, 'frame_total' : frame_total, - 'channel_total' : channnel_total, + 'channel_total' : channel_total, 'sample_rate' : sample_rate, 'bit_rate' : bit_rate } diff --git a/tests/test_api_assets.py b/tests/test_api_assets.py index 57953df1..277e67d5 100644 --- a/tests/test_api_assets.py +++ b/tests/test_api_assets.py @@ -7,7 +7,6 @@ from starlette.testclient import TestClient from facefusion import metadata, session_manager, state_manager from facefusion.apis import asset_store from facefusion.apis.core import create_api -from facefusion.common_helper import is_windows from facefusion.download import conditional_download from .assert_helper import get_test_example_file, get_test_examples_directory @@ -296,10 +295,6 @@ def test_upload_asset_security_strategies(test_client : TestClient) -> None: source_path = get_test_example_file('source.jpg') target_path = get_test_example_file('target-240p.mp4') - if is_windows(): - # todo - fix mp4 file to work with sanitize method under windows - pytest.skip() - for strategy in [ 'strict', 'moderate' ]: state_manager.init_item('api_security_strategy', strategy)