mirror of
https://github.com/facefusion/facefusion.git
synced 2026-09-15 20:15:28 +02:00
Goodbye tqdm (#1221)
* Goodbye tqdm * Goodbye tqdm * remove unused api * show just file name * support different mode * support different mode * minor polishing * minor polishing * switch to ProgressUnit to avoid confusion with ProcessMode * improve naming
This commit is contained in:
+10
-1
@@ -2,7 +2,7 @@ import logging
|
||||
from typing import List, Sequence, get_args
|
||||
|
||||
from facefusion.common_helper import create_float_range, create_int_range
|
||||
from facefusion.types import Angle, ApiSecurityStrategy, AudioEncoder, AudioFormat, AudioSet, BenchmarkMode, BenchmarkResolution, BenchmarkSet, DownloadProvider, DownloadProviderSet, DownloadScope, ExecutionProvider, ExecutionProviderSet, FaceAlignerModel, FaceDetectorModel, FaceDetectorSet, FaceMaskArea, FaceMaskAreaSet, FaceMaskRegion, FaceMaskRegionSet, FaceMaskType, FaceOccluderModel, FaceParserModel, FaceSelectorGender, FaceSelectorMode, FaceSelectorOrder, FaceSelectorRace, Gender, ImageEncoder, ImageFormat, ImageSet, JobStatus, LogLevel, LogLevelSet, Race, Score, TempFrameFormat, TempPixelFormat, VideoEncoder, VideoFormat, VideoMemoryStrategy, VideoPreset, VideoSet, VoiceExtractorModel, WorkflowMode, WorkflowStrategy
|
||||
from facefusion.types import Angle, ApiSecurityStrategy, AudioEncoder, AudioFormat, AudioSet, BenchmarkMode, BenchmarkResolution, BenchmarkSet, DownloadProvider, DownloadProviderSet, DownloadScope, ExecutionProvider, ExecutionProviderSet, FaceAlignerModel, FaceDetectorModel, FaceDetectorSet, FaceMaskArea, FaceMaskAreaSet, FaceMaskRegion, FaceMaskRegionSet, FaceMaskType, FaceOccluderModel, FaceParserModel, FaceSelectorGender, FaceSelectorMode, FaceSelectorOrder, FaceSelectorRace, Gender, ImageEncoder, ImageFormat, ImageSet, JobStatus, LogLevel, LogLevelSet, ProgressActionSet, Race, Score, TempFrameFormat, TempPixelFormat, VideoEncoder, VideoFormat, VideoMemoryStrategy, VideoPreset, VideoSet, VoiceExtractorModel, WorkflowMode, WorkflowStrategy
|
||||
|
||||
face_detector_set : FaceDetectorSet =\
|
||||
{
|
||||
@@ -151,6 +151,15 @@ log_level_set : LogLevelSet =\
|
||||
}
|
||||
log_levels : List[LogLevel] = list(get_args(LogLevel))
|
||||
|
||||
progress_action_set : ProgressActionSet =\
|
||||
{
|
||||
'color_active': '\033[94m',
|
||||
'color_neutral': '\033[90m',
|
||||
'cursor_start': '\033[G',
|
||||
'erase_line': '\033[K',
|
||||
'reset': '\033[0m'
|
||||
}
|
||||
|
||||
job_statuses : List[JobStatus] = list(get_args(JobStatus))
|
||||
|
||||
benchmark_cycle_count_range : Sequence[int] = create_int_range(1, 10, 1)
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
from contextlib import contextmanager
|
||||
from functools import partial
|
||||
from types import SimpleNamespace
|
||||
from typing import Iterator, Sized
|
||||
|
||||
from facefusion import choices
|
||||
from facefusion.types import ProgressUnit
|
||||
|
||||
|
||||
@contextmanager
|
||||
def create(unit : ProgressUnit = 'frame', current : int = 0, total : int = 0) -> Iterator[SimpleNamespace]:
|
||||
progress = SimpleNamespace(
|
||||
unit = unit,
|
||||
current = current,
|
||||
total = total,
|
||||
time_start = time.monotonic(),
|
||||
time_update = 0.0
|
||||
)
|
||||
progress.count = partial(count, progress)
|
||||
progress.set_title = partial(set_title, progress)
|
||||
progress.set_description = partial(set_description, progress)
|
||||
progress.update = partial(update, progress)
|
||||
progress.seek = partial(seek, progress)
|
||||
|
||||
yield progress
|
||||
|
||||
progress.current = progress.total
|
||||
render(progress)
|
||||
|
||||
sys.stdout.flush()
|
||||
sys.stdout.write(os.linesep)
|
||||
|
||||
|
||||
def set_title(progress : SimpleNamespace, title : str) -> None:
|
||||
progress.title = title
|
||||
|
||||
|
||||
def set_description(progress : SimpleNamespace, description : str) -> None:
|
||||
progress.description = description
|
||||
|
||||
|
||||
def count(progress : SimpleNamespace, collection : Sized) -> None:
|
||||
progress.total = len(collection)
|
||||
|
||||
|
||||
def update(progress : SimpleNamespace) -> None:
|
||||
seek(progress, progress.current + 1)
|
||||
|
||||
|
||||
def seek(progress : SimpleNamespace, current : int) -> None:
|
||||
progress.current = current
|
||||
time_current = time.monotonic()
|
||||
|
||||
if time_current - progress.time_update > 0.5:
|
||||
progress.time_update = time_current
|
||||
render(progress)
|
||||
|
||||
|
||||
def render(progress : SimpleNamespace) -> None:
|
||||
title = getattr(progress, 'title', '')
|
||||
description = getattr(progress, 'description', '')
|
||||
status = str(progress.current)
|
||||
|
||||
if progress.unit == 'percent':
|
||||
status = resolve_percent(progress)
|
||||
|
||||
if progress.unit == 'frame':
|
||||
status = resolve_frame(progress)
|
||||
|
||||
if progress.unit == 'download':
|
||||
status = resolve_download(progress)
|
||||
|
||||
progress_width = shutil.get_terminal_size().columns - len(title) - len(status) - 2
|
||||
|
||||
if description:
|
||||
progress_width -= len(description) + 3
|
||||
|
||||
if progress.total > 0:
|
||||
progress_fill = progress.current * progress_width // progress.total
|
||||
else:
|
||||
progress_fill = 0
|
||||
|
||||
progress_bar = choices.progress_action_set.get('color_active') + '=' * progress_fill + choices.progress_action_set.get('color_neutral') + '=' * (progress_width - progress_fill) + choices.progress_action_set.get('reset')
|
||||
progress_parts = [ title, progress_bar, status ]
|
||||
|
||||
if description:
|
||||
progress_parts.append('|')
|
||||
progress_parts.append(description)
|
||||
|
||||
sys.stdout.write(choices.progress_action_set.get('cursor_start') + ' '.join(progress_parts) + choices.progress_action_set.get('erase_line'))
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def resolve_percent(progress : SimpleNamespace) -> str:
|
||||
if progress.total > 0:
|
||||
percent = progress.current * 100 // progress.total
|
||||
return str(percent) + ' %'
|
||||
|
||||
return '0 %'
|
||||
|
||||
|
||||
def resolve_frame(progress : SimpleNamespace) -> str:
|
||||
time_current = time.monotonic()
|
||||
|
||||
if time_current - progress.time_start > 0:
|
||||
rate = progress.current / (time_current - progress.time_start)
|
||||
return str(round(rate, 1)) + 'frame/s'
|
||||
|
||||
return '0.0frame/s'
|
||||
|
||||
|
||||
def resolve_download(progress : SimpleNamespace) -> str:
|
||||
time_current = time.monotonic()
|
||||
|
||||
if time_current - progress.time_start > 0:
|
||||
rate = progress.current / (time_current - progress.time_start)
|
||||
|
||||
if rate > 1024 * 1024:
|
||||
return str(round(rate / (1024 * 1024), 1)) + 'mb/s'
|
||||
|
||||
return str(round(rate / 1024, 1)) + 'kb/s'
|
||||
|
||||
return '0.0kb/s'
|
||||
@@ -2,9 +2,8 @@ from functools import lru_cache
|
||||
from typing import Tuple
|
||||
|
||||
import numpy
|
||||
from tqdm import tqdm
|
||||
|
||||
from facefusion import inference_manager, state_manager, translator, video_manager
|
||||
from facefusion import cli_progress, inference_manager, translator, video_manager
|
||||
from facefusion.download import conditional_download_hashes, conditional_download_sources, resolve_download_url
|
||||
from facefusion.filesystem import resolve_relative_path
|
||||
from facefusion.thread_helper import conditional_thread_semaphore
|
||||
@@ -166,7 +165,9 @@ def analyse_video(video_path : str, trim_frame_start : int, trim_frame_end : int
|
||||
if trim_frame_start > 0:
|
||||
video_manager.seek_video_reader(video_reader, trim_frame_start)
|
||||
|
||||
with tqdm(total = len(frame_range), desc = translator.get('analysing'), unit = 'frame', ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
||||
with cli_progress.create(unit = 'frame') as progress:
|
||||
progress.set_title(translator.get('analysing'))
|
||||
progress.count(frame_range)
|
||||
|
||||
for frame_number in frame_range:
|
||||
vision_frame = video_manager.read_video_frame(video_reader)
|
||||
@@ -181,7 +182,7 @@ def analyse_video(video_path : str, trim_frame_start : int, trim_frame_end : int
|
||||
if counter > 0 and total > 0:
|
||||
rate = counter / total * 100
|
||||
|
||||
progress.set_postfix(rate = rate)
|
||||
progress.set_description('rate = ' + str(rate))
|
||||
progress.update()
|
||||
|
||||
return bool(rate > 10.0)
|
||||
|
||||
+1
-2
@@ -101,8 +101,7 @@ def pre_check() -> bool:
|
||||
|
||||
def common_pre_check() -> bool:
|
||||
content_analyser_content = inspect.getsource(content_analyser).encode()
|
||||
|
||||
return hash_helper.create_hash(content_analyser_content) == '3c6ce25e'
|
||||
return hash_helper.create_hash(content_analyser_content) == '61e33ef3'
|
||||
|
||||
|
||||
def processors_pre_check() -> bool:
|
||||
|
||||
@@ -4,10 +4,8 @@ from functools import lru_cache
|
||||
from typing import List, Optional, Tuple
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from tqdm import tqdm
|
||||
|
||||
import facefusion.choices
|
||||
from facefusion import curl_builder, logger, process_manager, state_manager, translator
|
||||
from facefusion import cli_progress, curl_builder, logger, process_manager, state_manager, translator
|
||||
from facefusion.filesystem import get_file_name, get_file_size, is_file, remove_file
|
||||
from facefusion.hash_helper import validate_hash
|
||||
from facefusion.types import Buffer, Command, DownloadProvider, DownloadSet
|
||||
@@ -26,7 +24,10 @@ def conditional_download(download_directory_path : str, urls : List[str]) -> Non
|
||||
download_size = get_static_download_size(url)
|
||||
|
||||
if initial_size < download_size:
|
||||
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 cli_progress.create(unit = 'download', total = download_size) as progress:
|
||||
progress.set_title(translator.get('downloading'))
|
||||
progress.set_description('file_name = ' + download_file_name)
|
||||
|
||||
commands = curl_builder.chain(
|
||||
curl_builder.download(url, download_file_path),
|
||||
curl_builder.set_timeout(5),
|
||||
@@ -34,12 +35,11 @@ def conditional_download(download_directory_path : str, urls : List[str]) -> Non
|
||||
)
|
||||
open_curl(commands)
|
||||
current_size = initial_size
|
||||
progress.set_postfix(download_providers = state_manager.get_item('download_providers'), file_name = download_file_name)
|
||||
|
||||
while current_size < download_size:
|
||||
if is_file(download_file_path):
|
||||
current_size = get_file_size(download_file_path)
|
||||
progress.update(current_size - progress.n)
|
||||
progress.seek(current_size)
|
||||
|
||||
|
||||
@lru_cache(maxsize = 64)
|
||||
|
||||
+11
-14
@@ -1,13 +1,11 @@
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
from functools import lru_cache, partial
|
||||
from functools import lru_cache
|
||||
from typing import List, Optional, cast
|
||||
|
||||
from tqdm import tqdm
|
||||
|
||||
import facefusion.choices
|
||||
from facefusion import ffmpeg_builder, ffprobe, logger, process_manager, state_manager, translator, vision
|
||||
from facefusion import cli_progress, ffmpeg_builder, ffprobe, logger, process_manager, state_manager, translator, vision
|
||||
from facefusion.filesystem import get_file_format, remove_file
|
||||
from facefusion.temp_helper import get_temp_file_path, get_temp_frames_pattern
|
||||
from facefusion.types import ApiSecurityStrategy, AudioEncoder, Buffer, Command, EncoderSet, Fps, Resolution, SampleRate, UpdateProgress, VideoEncoder, VideoFormat, VideoReaderMetadata
|
||||
@@ -40,10 +38,6 @@ def run_ffmpeg_with_progress(commands : List[Command], update_progress : UpdateP
|
||||
return process
|
||||
|
||||
|
||||
def update_progress(progress : tqdm, frame_number : int) -> None:
|
||||
progress.update(frame_number - progress.n)
|
||||
|
||||
|
||||
def run_ffmpeg_with_pipe(commands : List[Command], file_content : Buffer) -> subprocess.Popen[Buffer]:
|
||||
commands = ffmpeg_builder.run(commands)
|
||||
process = subprocess.Popen(commands, stdin = subprocess.PIPE, stderr = subprocess.PIPE, stdout = subprocess.PIPE)
|
||||
@@ -184,8 +178,9 @@ def extract_frames(target_path : str, output_path : str, temp_video_resolution :
|
||||
ffmpeg_builder.set_output(temp_frames_pattern)
|
||||
)
|
||||
|
||||
with tqdm(total = extract_frame_total, desc = translator.get('extracting'), unit = 'frame', ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
||||
process = run_ffmpeg_with_progress(commands, partial(update_progress, progress))
|
||||
with cli_progress.create(total = extract_frame_total) as progress:
|
||||
progress.set_title(translator.get('extracting'))
|
||||
process = run_ffmpeg_with_progress(commands, progress.seek)
|
||||
return process.returncode == 0
|
||||
|
||||
|
||||
@@ -202,8 +197,9 @@ def spawn_frames(target_path : str, output_path : str, temp_video_resolution : R
|
||||
ffmpeg_builder.set_output(temp_frames_pattern)
|
||||
)
|
||||
|
||||
with tqdm(total = spawn_frame_total, desc = translator.get('spawning'), unit = 'frame', ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
||||
process = run_ffmpeg_with_progress(commands, partial(update_progress, progress))
|
||||
with cli_progress.create(total = spawn_frame_total) as progress:
|
||||
progress.set_title(translator.get('spawning'))
|
||||
process = run_ffmpeg_with_progress(commands, progress.seek)
|
||||
return process.returncode == 0
|
||||
|
||||
|
||||
@@ -328,8 +324,9 @@ def merge_video(target_path : str, output_path : str, temp_video_fps : Fps, outp
|
||||
ffmpeg_builder.force_output(temp_video_path)
|
||||
)
|
||||
|
||||
with tqdm(total = merge_frame_total, desc = translator.get('merging'), unit = 'frame', ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
||||
process = run_ffmpeg_with_progress(commands, partial(update_progress, progress))
|
||||
with cli_progress.create(total = merge_frame_total) as progress:
|
||||
progress.set_title(translator.get('merging'))
|
||||
process = run_ffmpeg_with_progress(commands, progress.seek)
|
||||
return process.returncode == 0
|
||||
|
||||
|
||||
|
||||
@@ -5,9 +5,8 @@ from concurrent.futures import ThreadPoolExecutor
|
||||
from typing import Deque, Iterator, List
|
||||
|
||||
import cv2
|
||||
from tqdm import tqdm
|
||||
|
||||
from facefusion import ffmpeg_builder, logger, state_manager, translator
|
||||
from facefusion import cli_progress, ffmpeg_builder, logger, state_manager, translator
|
||||
from facefusion.audio import create_empty_audio_frame
|
||||
from facefusion.content_analyser import analyse_stream
|
||||
from facefusion.ffmpeg import open_ffmpeg
|
||||
@@ -21,7 +20,9 @@ def multi_process_capture(camera_capture : cv2.VideoCapture, camera_fps : Fps) -
|
||||
capture_deque : Deque[VisionFrame] = deque()
|
||||
source_vision_frames = read_static_images(state_manager.get_item('source_paths'))
|
||||
|
||||
with tqdm(desc = translator.get('streaming'), unit = 'frame', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
||||
with cli_progress.create() as progress:
|
||||
progress.set_title(translator.get('streaming'))
|
||||
|
||||
with ThreadPoolExecutor(max_workers = state_manager.get_item('execution_thread_count')) as executor:
|
||||
futures = []
|
||||
|
||||
|
||||
@@ -177,6 +177,10 @@ ErrorCode = Literal[0, 1, 2, 3, 4]
|
||||
LogLevel = Literal['error', 'warn', 'info', 'debug']
|
||||
LogLevelSet : TypeAlias = Dict[LogLevel, int]
|
||||
|
||||
ProgressAction = Literal['color_active', 'color_neutral', 'cursor_start', 'erase_line', 'reset']
|
||||
ProgressActionSet : TypeAlias = Dict[ProgressAction, str]
|
||||
ProgressUnit = Literal['percent', 'frame', 'download']
|
||||
|
||||
TableHeader : TypeAlias = str
|
||||
TableContent : TypeAlias = Any
|
||||
|
||||
|
||||
@@ -3,9 +3,8 @@ from concurrent.futures import Future, ThreadPoolExecutor
|
||||
from typing import Deque, List
|
||||
|
||||
import numpy
|
||||
from tqdm import tqdm
|
||||
|
||||
from facefusion import logger, process_manager, state_manager, translator
|
||||
from facefusion import cli_progress, logger, process_manager, state_manager, translator
|
||||
from facefusion.audio import create_empty_audio_frame, get_audio_frame, get_voice_frame
|
||||
from facefusion.common_helper import get_first
|
||||
from facefusion.filesystem import filter_audio_paths, get_file_extension, has_audio, has_image, has_video
|
||||
@@ -150,8 +149,9 @@ def process_frames() -> ErrorCode:
|
||||
temp_frame_set = resolve_temp_frame_set(state_manager.get_temp_path(), state_manager.get_item('output_path'), state_manager.get_item('temp_frame_format'))
|
||||
|
||||
if temp_frame_set:
|
||||
with tqdm(total = len(temp_frame_set), desc = translator.get('processing'), unit = 'frame', ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
||||
progress.set_postfix(execution_providers = state_manager.get_item('execution_providers'))
|
||||
with cli_progress.create(unit = 'frame') as progress:
|
||||
progress.set_title(translator.get('processing'))
|
||||
progress.count(temp_frame_set)
|
||||
|
||||
with ThreadPoolExecutor(max_workers = state_manager.get_item('execution_thread_count')) as executor:
|
||||
futures : Deque[Future[bool]] = deque()
|
||||
|
||||
@@ -4,9 +4,8 @@ from typing import Deque
|
||||
|
||||
import cv2
|
||||
import numpy
|
||||
from tqdm import tqdm
|
||||
|
||||
from facefusion import content_analyser, ffmpeg, logger, process_manager, state_manager, translator, video_manager
|
||||
from facefusion import cli_progress, content_analyser, ffmpeg, logger, process_manager, state_manager, translator, video_manager
|
||||
from facefusion.common_helper import get_first, get_middle
|
||||
from facefusion.filesystem import filter_audio_paths, is_video
|
||||
from facefusion.media_helper import restrict_trim_frame
|
||||
@@ -75,8 +74,9 @@ def process_memory_frames() -> ErrorCode:
|
||||
if temp_frame_range:
|
||||
video_writer = video_manager.get_writer(state_manager.get_item('output_path'), temp_video_fps, output_video_resolution, output_video_resolution, state_manager.get_item('output_video_fps'))
|
||||
|
||||
with tqdm(total = len(temp_frame_range), desc = translator.get('processing'), unit = 'frame', ascii = ' =', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress:
|
||||
progress.set_postfix(execution_providers = state_manager.get_item('execution_providers'))
|
||||
with cli_progress.create(unit = 'frame') as progress:
|
||||
progress.set_title(translator.get('processing'))
|
||||
progress.count(temp_frame_range)
|
||||
|
||||
read_static_video_frame(state_manager.get_item('target_path'), state_manager.get_item('reference_frame_number'))
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ onnxruntime==1.28.0
|
||||
opencv-python-headless==5.0.0.93
|
||||
psutil==7.2.2
|
||||
python-multipart==0.0.28
|
||||
tqdm==4.70.0
|
||||
scipy==1.18.0
|
||||
starlette==0.52.1
|
||||
uvicorn==0.41.0
|
||||
|
||||
Reference in New Issue
Block a user