from typing import List, Optional, Tuple import gradio import os import requests import tempfile from PIL import ImageGrab, Image # Para manejar imágenes desde el portapapeles from ffff import state_manager, wording from ffff.common_helper import get_first from ffff.filesystem import filter_audio_paths, filter_image_paths, has_audio, has_image, is_video, get_file_size from ffff.vision import get_video_frame, normalize_frame_color from ffff.uis.core import register_ui_component from ffff.uis.typing import File FILE_SIZE_LIMIT = 512 * 1024 * 1024 # Variables globales para almacenar el archivo cargado SOURCE_FILE: Optional[gradio.File] = None SOURCE_IMAGE: Optional[gradio.Image] = None SOURCE_VIDEO: Optional[gradio.Video] = None def render() -> None: global SOURCE_FILE global SOURCE_IMAGE global SOURCE_VIDEO has_source_audio = has_audio(state_manager.get_item('source_paths')) has_source_image = has_image(state_manager.get_item('source_paths')) has_source_video = is_video(state_manager.get_item('source_paths')) SOURCE_FILE = gradio.File( file_count='single', file_types=['image', 'video'], label=wording.get('uis.source_file'), value=state_manager.get_item('source_paths') if has_source_audio or has_source_image or has_source_video else None ) source_file_path = state_manager.get_item('source_paths')[0] if state_manager.get_item('source_paths') else None source_image_args = {'show_label': False, 'visible': False} source_video_args = {'show_label': False, 'visible': False} if has_source_image: source_image_args['value'] = source_file_path source_image_args['visible'] = True if has_source_video: if get_file_size(source_file_path) > FILE_SIZE_LIMIT: preview_vision_frame = normalize_frame_color(get_video_frame(source_file_path)) source_image_args['value'] = preview_vision_frame source_image_args['visible'] = True else: source_video_args['value'] = source_file_path source_video_args['visible'] = True SOURCE_IMAGE = gradio.Image(**source_image_args) SOURCE_VIDEO = gradio.Video(**source_video_args) register_ui_component('source_image', SOURCE_IMAGE) register_ui_component('source_video', SOURCE_VIDEO) def listen() -> None: SOURCE_FILE.change(update, inputs=SOURCE_FILE, outputs=[SOURCE_IMAGE, SOURCE_VIDEO]) def update(file: File) -> Tuple[gradio.Image, gradio.Video]: if file and has_image([file.name]): state_manager.set_item('source_paths', [file.name]) return gradio.Image(value=file.name, visible=True), gradio.Video(value=None, visible=False) if file and is_video(file.name): state_manager.set_item('source_paths', [file.name]) if get_file_size(file.name) > FILE_SIZE_LIMIT: preview_vision_frame = normalize_frame_color(get_video_frame(file.name)) return gradio.Image(value=preview_vision_frame, visible=True), gradio.Video(value=None, visible=False) return gradio.Image(value=None, visible=False), gradio.Video(value=file.name, visible=True) state_manager.clear_item('source_paths') return gradio.Image(value=None, visible=False), gradio.Video(value=None, visible=False) # Función para descargar un archivo desde URL def download_file_from_url(url: str) -> Optional[str]: try: response = requests.get(url, stream=True) response.raise_for_status() temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(url)[-1]) with open(temp_file.name, 'wb') as file: for chunk in response.iter_content(chunk_size=8192): file.write(chunk) return temp_file.name except Exception as e: print(f"Error al descargar el archivo: {e}") return None def handle_url_input(url: str) -> Tuple[gradio.Image, gradio.Video]: downloaded_file_path = download_file_from_url(url) if downloaded_file_path: state_manager.set_item('source_paths', [downloaded_file_path]) if has_image([downloaded_file_path]): return gradio.Image(value=downloaded_file_path, visible=True), gradio.Video(value=None, visible=False) if is_video(downloaded_file_path): if get_file_size(downloaded_file_path) > FILE_SIZE_LIMIT: preview_vision_frame = normalize_frame_color(get_video_frame(downloaded_file_path)) return gradio.Image(value=preview_vision_frame, visible=True), gradio.Video(value=None, visible=False) return gradio.Image(value=None, visible=False), gradio.Video(value=downloaded_file_path, visible=True) return gradio.Image(value=None, visible=False), gradio.Video(value=None, visible=False) def handle_paste() -> Tuple[gradio.Image, gradio.Video]: try: image = ImageGrab.grabclipboard() if isinstance(image, Image.Image): temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png") image.save(temp_file.name) state_manager.set_item('source_paths', [temp_file.name]) return gradio.Image(value=temp_file.name, visible=True), gradio.Video(value=None, visible=False) except Exception as e: print(f"Error al manejar el portapapeles: {e}") return gradio.Image(value=None, visible=False), gradio.Video(value=None, visible=False) def cargar_archivo(archivo_seleccionado: str) -> Tuple[gradio.Image, gradio.Video]: state_manager.set_item('source_paths', [archivo_seleccionado]) if has_image([archivo_seleccionado]): return gradio.Image(value=archivo_seleccionado, visible=True), gradio.Video(value=None, visible=False) if is_video(archivo_seleccionado): return gradio.Image(value=None, visible=False), gradio.Video(value=archivo_seleccionado, visible=True) return gradio.Image(value=None, visible=False), gradio.Video(value=None, visible=False)