mirror of
https://github.com/facefusion/facefusion.git
synced 2026-05-13 02:34:43 +02:00
57fcb86b82
* mark as next * add fran model * add support for corridor key (#1060) * introduce despill color * simplify the apply dispill color * finalize naming for both fill and despill * follow vision_frame convension * patch fran model * adjust fran urls * Feat/dynamic env setup (#1061) * dynamic environment setup * dynamic environment setup * fix fran model * prevent directml using incompatible corridor_key model * fix environment setup for windows * switch to corridor_key_1024 and corridor_key_2048 * switch to corridor_key_1024 and corridor_key_2048 * mark it as 3.6.0 * rename environment to conda * rename environment to conda * fix testing for face analyser * some background remove cosmetics * some background remove cosmetics * some background remove cosmetics * update preview --------- Co-authored-by: harisreedhar <h4harisreedhar.s.s@gmail.com>
101 lines
3.7 KiB
Python
101 lines
3.7 KiB
Python
import os
|
|
import subprocess
|
|
from collections import deque
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
from typing import Deque, Iterator
|
|
|
|
import cv2
|
|
import numpy
|
|
from tqdm import tqdm
|
|
|
|
from facefusion import 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
|
|
from facefusion.filesystem import is_directory
|
|
from facefusion.processors.core import get_processors_modules
|
|
from facefusion.types import Fps, StreamMode, VisionFrame
|
|
from facefusion.vision import extract_vision_mask, read_static_images
|
|
|
|
|
|
def multi_process_capture(camera_capture : cv2.VideoCapture, camera_fps : Fps) -> Iterator[VisionFrame]:
|
|
capture_deque : Deque[VisionFrame] = deque()
|
|
|
|
with tqdm(desc = translator.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 camera_capture and camera_capture.isOpened():
|
|
_, capture_vision_frame = camera_capture.read()
|
|
if analyse_stream(capture_vision_frame, camera_fps):
|
|
camera_capture.release()
|
|
|
|
if numpy.any(capture_vision_frame):
|
|
future = executor.submit(process_stream_frame, capture_vision_frame)
|
|
futures.append(future)
|
|
|
|
for future_done in [ future for future in futures if future.done() ]:
|
|
capture_vision_frame = future_done.result()
|
|
capture_deque.append(capture_vision_frame)
|
|
futures.remove(future_done)
|
|
|
|
while capture_deque:
|
|
progress.update()
|
|
yield capture_deque.popleft()
|
|
|
|
|
|
def process_stream_frame(target_vision_frame : VisionFrame) -> VisionFrame:
|
|
source_vision_frames = read_static_images(state_manager.get_item('source_paths'))
|
|
source_audio_frame = create_empty_audio_frame()
|
|
source_voice_frame = create_empty_audio_frame()
|
|
temp_vision_frame = target_vision_frame.copy()
|
|
temp_vision_mask = extract_vision_mask(temp_vision_frame)
|
|
|
|
for processor_module in get_processors_modules(state_manager.get_item('processors')):
|
|
logger.disable()
|
|
if processor_module.pre_process('stream'):
|
|
logger.enable()
|
|
temp_vision_frame, temp_vision_mask = processor_module.process_frame(
|
|
{
|
|
'source_vision_frames': source_vision_frames,
|
|
'source_audio_frame': source_audio_frame,
|
|
'source_voice_frame': source_voice_frame,
|
|
'target_vision_frame': target_vision_frame,
|
|
'temp_vision_frame': temp_vision_frame,
|
|
'temp_vision_mask': temp_vision_mask
|
|
})
|
|
logger.enable()
|
|
|
|
return temp_vision_frame
|
|
|
|
|
|
def open_stream(stream_mode : StreamMode, stream_resolution : str, stream_fps : Fps) -> subprocess.Popen[bytes]:
|
|
commands = ffmpeg_builder.chain(
|
|
ffmpeg_builder.capture_video(),
|
|
ffmpeg_builder.set_media_resolution(stream_resolution),
|
|
ffmpeg_builder.set_input_fps(stream_fps)
|
|
)
|
|
|
|
if stream_mode == 'udp':
|
|
commands.extend(ffmpeg_builder.set_input('-'))
|
|
commands.extend(ffmpeg_builder.set_stream_mode('udp'))
|
|
commands.extend(ffmpeg_builder.set_stream_quality(2000))
|
|
commands.extend(ffmpeg_builder.set_output('udp://localhost:27000?pkt_size=1316'))
|
|
|
|
if stream_mode == 'v4l2':
|
|
device_directory_path = '/sys/devices/virtual/video4linux'
|
|
commands.extend(ffmpeg_builder.set_input('-'))
|
|
commands.extend(ffmpeg_builder.set_stream_mode('v4l2'))
|
|
|
|
if is_directory(device_directory_path):
|
|
device_names = os.listdir(device_directory_path)
|
|
|
|
for device_name in device_names:
|
|
device_path = '/dev/' + device_name
|
|
commands.extend(ffmpeg_builder.set_output(device_path))
|
|
|
|
else:
|
|
logger.error(translator.get('stream_not_loaded').format(stream_mode = stream_mode), __name__)
|
|
|
|
return open_ffmpeg(commands)
|