Feat/commands builder (#852)

* Protype for ffmpeg builder

* Protype for ffmpeg builder

* Add curl builder

* Fix typing import

* Adjust commands indent

* Protype for ffmpeg builder part2

* Protype for ffmpeg builder part3

* Protype for ffmpeg builder part3

* Add chain() helper to the builders

* Protype for ffmpeg builder part4

* Protype for ffmpeg builder part5

* Protoype for ffmpeg builder part5

* Protoype for ffmpeg builder part6

* Allow dynamic audio size

* Fix testing

* Protoype for ffmpeg builder part7

* Fix and polish ffmpeg builder

* Hardcode the log level for ffmpeg

* More ffmpeg rework

* Prototype for ffmpeg builder part8

* Prototype for ffmpeg builder part9

* Fix CI

* Fix Styles

* Add lazy testing, User Agent for CURL

* More testing

* More testing
This commit is contained in:
Henry Ruhs
2025-01-13 10:42:40 +01:00
committed by henryruhs
parent 7f90ca72bb
commit 8a9e08f3a2
16 changed files with 491 additions and 188 deletions

View File

@@ -1,11 +1,9 @@
from typing import List
from facefusion.uis.typing import JobManagerAction, JobRunnerAction, WebcamMode
from facefusion.uis.typing import JobManagerAction, JobRunnerAction
job_manager_actions : List[JobManagerAction] = [ 'job-create', 'job-submit', 'job-delete', 'job-add-step', 'job-remix-step', 'job-insert-step', 'job-remove-step' ]
job_runner_actions : List[JobRunnerAction] = [ 'job-run', 'job-run-all', 'job-retry', 'job-retry-all' ]
common_options : List[str] = [ 'keep-temp' ]
webcam_modes : List[WebcamMode] = [ 'inline', 'udp', 'v4l2' ]
webcam_resolutions : List[str] = [ '320x240', '640x480', '800x600', '1024x768', '1280x720', '1280x960', '1920x1080', '2560x1440', '3840x2160' ]

View File

@@ -6,7 +6,7 @@ import facefusion.choices
from facefusion import state_manager, wording
from facefusion.common_helper import calc_int_step
from facefusion.filesystem import is_image, is_video
from facefusion.typing import Fps, OutputAudioEncoder, OutputVideoEncoder, OutputVideoPreset
from facefusion.typing import AudioEncoder, Fps, VideoEncoder, VideoPreset
from facefusion.uis.core import get_ui_components, register_ui_component
from facefusion.vision import create_image_resolutions, create_video_resolutions, detect_image_resolution, detect_video_fps, detect_video_resolution, pack_resolution
@@ -159,7 +159,7 @@ def update_output_image_resolution(output_image_resolution : str) -> None:
state_manager.set_item('output_image_resolution', output_image_resolution)
def update_output_audio_encoder(output_audio_encoder : OutputAudioEncoder) -> None:
def update_output_audio_encoder(output_audio_encoder : AudioEncoder) -> None:
state_manager.set_item('output_audio_encoder', output_audio_encoder)
@@ -171,11 +171,11 @@ def update_output_audio_volume(output_audio_volume: float) -> None:
state_manager.set_item('output_audio_volume', int(output_audio_volume))
def update_output_video_encoder(output_video_encoder : OutputVideoEncoder) -> None:
def update_output_video_encoder(output_video_encoder : VideoEncoder) -> None:
state_manager.set_item('output_video_encoder', output_video_encoder)
def update_output_video_preset(output_video_preset : OutputVideoPreset) -> None:
def update_output_video_preset(output_video_preset : VideoPreset) -> None:
state_manager.set_item('output_video_preset', output_video_preset)

View File

@@ -8,17 +8,16 @@ import cv2
import gradio
from tqdm import tqdm
from facefusion import logger, state_manager, wording
from facefusion import ffmpeg_builder, logger, state_manager, wording
from facefusion.audio import create_empty_audio_frame
from facefusion.common_helper import get_first, is_windows
from facefusion.common_helper import is_windows
from facefusion.content_analyser import analyse_stream
from facefusion.face_analyser import get_average_face, get_many_faces
from facefusion.ffmpeg import open_ffmpeg
from facefusion.filesystem import filter_image_paths
from facefusion.filesystem import filter_image_paths, is_directory
from facefusion.processors.core import get_processors_modules
from facefusion.typing import Face, Fps, VisionFrame
from facefusion.typing import Face, Fps, StreamMode, VisionFrame, WebcamMode
from facefusion.uis.core import get_ui_component
from facefusion.uis.typing import StreamMode, WebcamMode
from facefusion.vision import normalize_frame_color, read_static_images, unpack_resolution
WEBCAM_CAPTURE : Optional[cv2.VideoCapture] = None
@@ -164,17 +163,32 @@ 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', '-']
commands = ffmpeg_builder.chain(
ffmpeg_builder.capture_video(),
ffmpeg_builder.set_media_resolution(stream_resolution),
ffmpeg_builder.set_conditional_fps(stream_fps)
)
if stream_mode == 'udp':
commands.extend([ '-b:v', '2000k', '-f', 'mpegts', 'udp://localhost:27000?pkt_size=1316' ])
commands.extend(ffmpeg_builder.set_input('-'))
commands.extend(ffmpeg_builder.set_stream_mode('udp'))
commands.extend(ffmpeg_builder.set_output('udp://localhost:27000?pkt_size=1316'))
if stream_mode == 'v4l2':
try:
device_name = get_first(os.listdir('/sys/devices/virtual/video4linux'))
if device_name:
commands.extend([ '-f', 'v4l2', '/dev/' + device_name ])
except FileNotFoundError:
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(wording.get('stream_not_loaded').format(stream_mode = stream_mode), __name__)
return open_ffmpeg(commands)

View File

@@ -2,9 +2,9 @@ from typing import Optional
import gradio
import facefusion.choices
from facefusion import wording
from facefusion.common_helper import get_first
from facefusion.uis import choices as uis_choices
from facefusion.uis.components.webcam import get_available_webcam_ids
from facefusion.uis.core import register_ui_component
@@ -28,13 +28,13 @@ def render() -> None:
)
WEBCAM_MODE_RADIO = gradio.Radio(
label = wording.get('uis.webcam_mode_radio'),
choices = uis_choices.webcam_modes,
choices = facefusion.choices.webcam_modes,
value = 'inline'
)
WEBCAM_RESOLUTION_DROPDOWN = gradio.Dropdown(
label = wording.get('uis.webcam_resolution_dropdown'),
choices = uis_choices.webcam_resolutions,
value = uis_choices.webcam_resolutions[0]
choices = facefusion.choices.webcam_resolutions,
value = facefusion.choices.webcam_resolutions[0]
)
WEBCAM_FPS_SLIDER = gradio.Slider(
label = wording.get('uis.webcam_fps_slider'),

View File

@@ -81,6 +81,3 @@ ComponentName = Literal\
JobManagerAction = Literal['job-create', 'job-submit', 'job-delete', 'job-add-step', 'job-remix-step', 'job-insert-step', 'job-remove-step']
JobRunnerAction = Literal['job-run', 'job-run-all', 'job-retry', 'job-retry-all']
WebcamMode = Literal['inline', 'udp', 'v4l2']
StreamMode = Literal['udp', 'v4l2']