diff --git a/facefusion/ffprobe.py b/facefusion/ffprobe.py index ebdb5375..a37266f3 100644 --- a/facefusion/ffprobe.py +++ b/facefusion/ffprobe.py @@ -48,10 +48,27 @@ def probe_video_entries(video_path : str, entries : List[str]) -> Dict[str, str] return parse_entries(output) +def probe_format_entries(video_path : str, entries : List[str]) -> Dict[str, str]: + commands = ffprobe_builder.chain( + ffprobe_builder.show_format_entries(entries), + ffprobe_builder.format_to_key_value(), + ffprobe_builder.set_input(video_path) + ) + output, _ = run_ffprobe(commands).communicate() + + return parse_entries(output) + + @lru_cache(maxsize = 128) def extract_video_metadata(video_path : str) -> VideoMetadata: video_entries = probe_video_entries(video_path, [ 'duration', 'width', 'height', 'r_frame_rate', 'bit_rate' ]) + if video_entries.get('duration') == 'N/A': + video_entries['duration'] = probe_format_entries(video_path, [ 'duration' ]).get('duration') + + if video_entries.get('bit_rate') == 'N/A': + video_entries['bit_rate'] = probe_format_entries(video_path, [ 'bit_rate' ]).get('bit_rate') + duration = float(video_entries.get('duration')) fps = extract_video_fps(video_entries.get('r_frame_rate')) frame_total = int(duration * fps) diff --git a/facefusion/ffprobe_builder.py b/facefusion/ffprobe_builder.py index 06b621f8..5266999a 100644 --- a/facefusion/ffprobe_builder.py +++ b/facefusion/ffprobe_builder.py @@ -21,6 +21,10 @@ def show_entries(entries : List[str]) -> List[Command]: return [ '-show_entries', 'stream=' + ','.join(entries) ] +def show_format_entries(entries : List[str]) -> List[Command]: + return [ '-show_entries', 'format=' + ','.join(entries) ] + + def format_to_value() -> List[Command]: return [ '-of', 'default=noprint_wrappers=1:nokey=1' ] diff --git a/facefusion/types.py b/facefusion/types.py index e4390908..29b55d2d 100755 --- a/facefusion/types.py +++ b/facefusion/types.py @@ -64,7 +64,7 @@ Language = Literal['en'] Locales : TypeAlias = Dict[Language, Dict[str, Any]] LocalePoolSet : TypeAlias = Dict[str, Locales] -VideoWriterSet : TypeAlias = Dict[str, subprocess.Popen] +VideoWriterSet : TypeAlias = Dict[str, subprocess.Popen[bytes]] CameraCaptureSet : TypeAlias = Dict[str, cv2.VideoCapture] CameraPoolSet = TypedDict('CameraPoolSet', { @@ -98,7 +98,7 @@ BitRate : TypeAlias = int VideoReaderBuffer : TypeAlias = Dict[int, VisionFrame] VideoReader = TypedDict('VideoReader', { - 'process' : subprocess.Popen, + 'process' : subprocess.Popen[bytes], 'video_path' : str, 'width' : int, 'height' : int, diff --git a/facefusion/video_manager.py b/facefusion/video_manager.py index 7fd3a2f8..cfd66960 100644 --- a/facefusion/video_manager.py +++ b/facefusion/video_manager.py @@ -47,7 +47,7 @@ def create_video_sampler_process(video_path : str, frame_start : int, frame_end commands = ffmpeg_builder.run(commands) if is_windows(): - return subprocess.Popen(commands, stdout = subprocess.PIPE, stderr = subprocess.DEVNULL, creationflags = subprocess.IDLE_PRIORITY_CLASS) + return subprocess.Popen(commands, stdout = subprocess.PIPE, stderr = subprocess.DEVNULL, creationflags = subprocess.IDLE_PRIORITY_CLASS) #type:ignore[attr-defined] return subprocess.Popen(commands, stdout = subprocess.PIPE, stderr = subprocess.DEVNULL, preexec_fn = demote_process_priority)