diff --git a/facefusion/uis/components/webcam.py b/facefusion/uis/components/webcam.py index cc3fcebf..444e0dc8 100644 --- a/facefusion/uis/components/webcam.py +++ b/facefusion/uis/components/webcam.py @@ -43,7 +43,7 @@ def get_webcam_capture() -> Optional[cv2.VideoCapture]: def clear_webcam_capture() -> None: global WEBCAM_CAPTURE - if WEBCAM_CAPTURE: + if WEBCAM_CAPTURE and WEBCAM_CAPTURE.isOpened(): WEBCAM_CAPTURE.release() WEBCAM_CAPTURE = None @@ -89,11 +89,13 @@ def start(webcam_mode : WebcamMode, webcam_resolution : str, webcam_fps : Fps) - stream = open_stream(webcam_mode, webcam_resolution, webcam_fps) #type:ignore[arg-type] webcam_width, webcam_height = unpack_resolution(webcam_resolution) webcam_capture = get_webcam_capture() + if webcam_capture and webcam_capture.isOpened(): webcam_capture.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG')) #type:ignore[attr-defined] webcam_capture.set(cv2.CAP_PROP_FRAME_WIDTH, webcam_width) webcam_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, webcam_height) webcam_capture.set(cv2.CAP_PROP_FPS, webcam_fps) + for capture_frame in multi_process_capture(source_face, webcam_capture, webcam_fps): if webcam_mode == 'inline': yield normalize_frame_color(capture_frame) @@ -107,19 +109,15 @@ def start(webcam_mode : WebcamMode, webcam_resolution : str, webcam_fps : Fps) - def multi_process_capture(source_face : Face, webcam_capture : cv2.VideoCapture, webcam_fps : Fps) -> Generator[VisionFrame, None, None]: deque_capture_frames: Deque[VisionFrame] = deque() - with tqdm(desc = wording.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'), - 'execution_thread_count': state_manager.get_item('execution_thread_count') - }) + + with tqdm(desc = wording.get('streaming'), unit = 'frame', disable = state_manager.get_item('log_level') in [ 'warn', 'error' ]) as progress: with ThreadPoolExecutor(max_workers = state_manager.get_item('execution_thread_count')) as executor: futures = [] while webcam_capture and webcam_capture.isOpened(): _, capture_frame = webcam_capture.read() if analyse_stream(capture_frame, webcam_fps): - return + yield None future = executor.submit(process_stream_frame, source_face, capture_frame) futures.append(future) @@ -140,6 +138,7 @@ def stop() -> gradio.Image: def process_stream_frame(source_face : Face, target_vision_frame : VisionFrame) -> VisionFrame: source_audio_frame = create_empty_audio_frame() + for processor_module in get_processors_modules(state_manager.get_item('processors')): logger.disable() if processor_module.pre_process('stream'): @@ -155,6 +154,7 @@ def process_stream_frame(source_face : Face, target_vision_frame : VisionFrame) def open_stream(stream_mode : StreamMode, stream_resolution : str, stream_fps : Fps) -> subprocess.Popen[bytes]: commands = [ '-f', 'rawvideo', '-pix_fmt', 'bgr24', '-s', stream_resolution, '-r', str(stream_fps), '-i', '-'] + if stream_mode == 'udp': commands.extend([ '-b:v', '2000k', '-f', 'mpegts', 'udp://localhost:27000?pkt_size=1316' ]) if stream_mode == 'v4l2': diff --git a/facefusion/uis/layouts/webcam.py b/facefusion/uis/layouts/webcam.py index 2351d081..6b059cc7 100644 --- a/facefusion/uis/layouts/webcam.py +++ b/facefusion/uis/layouts/webcam.py @@ -1,7 +1,7 @@ import gradio from facefusion import state_manager -from facefusion.uis.components import about, age_modifier_options, execution, execution_thread_count, face_debugger_options, face_enhancer_options, face_swapper_options, frame_colorizer_options, frame_enhancer_options, lip_syncer_options, processors, source, webcam, webcam_options +from facefusion.uis.components import about, age_modifier_options, execution, execution_thread_count, expression_restorer_options, face_debugger_options, face_editor_options, face_enhancer_options, face_swapper_options, frame_colorizer_options, frame_enhancer_options, lip_syncer_options, processors, source, webcam, webcam_options def pre_check() -> bool: @@ -18,8 +18,12 @@ def render() -> gradio.Blocks: processors.render() with gradio.Blocks(): age_modifier_options.render() + with gradio.Blocks(): + expression_restorer_options.render() with gradio.Blocks(): face_debugger_options.render() + with gradio.Blocks(): + face_editor_options.render() with gradio.Blocks(): face_enhancer_options.render() with gradio.Blocks(): @@ -46,7 +50,9 @@ def render() -> gradio.Blocks: def listen() -> None: processors.listen() age_modifier_options.listen() + expression_restorer_options.listen() face_debugger_options.listen() + face_editor_options.listen() face_enhancer_options.listen() face_swapper_options.listen() frame_colorizer_options.listen() diff --git a/facefusion/wording.py b/facefusion/wording.py index 2d831911..962f049f 100755 --- a/facefusion/wording.py +++ b/facefusion/wording.py @@ -12,6 +12,7 @@ WORDING : Dict[str, Any] =\ 'extracting_frames_failed': 'Extracting frames failed', 'analysing': 'Analysing', 'processing': 'Processing', + 'streaming': 'Streaming', 'downloading': 'Downloading', 'temp_frames_not_found': 'Temporary frames not found', 'copying_image': 'Copying image with a resolution of {resolution}',