import gradio as gr import cv2 import numpy as np from PIL import Image import os import tempfile from pathlib import Path import spaces from video_processor import VideoCharacterReplacer from utils import save_uploaded_file, cleanup_temp_files # Initialize the character replacer character_replacer = VideoCharacterReplacer() def process_video(reference_image, input_video, replacement_strength, detection_sensitivity, tracking_stability, preserve_background): """ Process video to replace character with reference image Args: reference_image (PIL.Image): Reference image of the character to replace with input_video (str): Path to input video file replacement_strength (float): Strength of character replacement (0-1) detection_sensitivity (float): Face detection sensitivity (0-1) tracking_stability (float): Tracking stability for temporal consistency (0-1) preserve_background (bool): Whether to preserve background lighting and colors Returns: tuple: (processed_video_path, info_message) """ if reference_image is None or input_video is None: return None, "Please provide both a reference image and input video." try: # Save uploaded files to temporary locations ref_path = save_uploaded_file(reference_image, ".jpg") video_path = save_uploaded_file(input_video, ".mp4") # Process the video output_path = character_replacer.replace_character( ref_image_path=ref_path, input_video_path=video_path, replacement_strength=replacement_strength, detection_sensitivity=detection_sensitivity, tracking_stability=tracking_stability, preserve_background=preserve_background ) # Cleanup temporary files cleanup_temp_files([ref_path, video_path]) if output_path and os.path.exists(output_path): return output_path, f"Character replacement completed successfully! Output saved to: {output_path}" else: return None, "Error: Failed to process video." except Exception as e: cleanup_temp_files([ref_path, video_path]) return None, f"Error processing video: {str(e)}" def extract_preview_frames(video_path, num_frames=4): """Extract preview frames from video for display""" if video_path is None: return None try: cap = cv2.VideoCapture(video_path) total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) fps = cap.get(cv2.CAP_PROP_FPS) duration = total_frames / fps if fps > 0 else 0 # Select frames evenly distributed across the video frame_indices = np.linspace(0, total_frames-1, num_frames, dtype=int) frames = [] for frame_idx in frame_indices: cap.set(cv2.CAP_PROP_POS_FRAMES, frame_idx) ret, frame = cap.read() if ret: frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) frames.append(Image.fromarray(frame_rgb)) cap.release() return frames except Exception as e: print(f"Error extracting preview frames: {e}") return [] # Create the Gradio interface with gr.Blocks(title="Video Character Replacement", theme=gr.themes.Base()) as demo: # Header gr.HTML("""
Replace characters in videos using AI-powered face detection and replacement