File size: 5,763 Bytes
adadce7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import gradio as gr
import os
import subprocess
import time
import logging
import psutil
from pathlib import Path

# Configuraci贸n de logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# Configuraci贸n de rutas
FFMPEG_PATH = os.path.join(os.getcwd(), "ffmpeg.exe")
UPLOADS_DIR = os.path.join(os.getcwd(), "uploads")

# Crear directorio de uploads si no existe
os.makedirs(UPLOADS_DIR, exist_ok=True)

# Formatos soportados
VIDEO_FORMATS = ['.mp4', '.avi', '.mov', '.mkv', '.wmv', '.flv', '.webm', '.m4v']
AUDIO_FORMATS = ['.mp3', '.wav', '.flac', '.aac', '.ogg', '.m4a', '.wma']
SUPPORTED_FORMATS = VIDEO_FORMATS + AUDIO_FORMATS

# Presets de compresi贸n
COMPRESSION_PRESETS = {
    "Compresi贸n R谩pida": {
        "video": "-c:v libx264 -preset ultrafast -crf 28",
        "audio": "-c:a aac -b:a 128k"
    },
    "Compresi贸n Media": {
        "video": "-c:v libx264 -preset medium -crf 23",
        "audio": "-c:a aac -b:a 128k"
    },
    "Compresi贸n Alta": {
        "video": "-c:v libx264 -preset slow -crf 20",
        "audio": "-c:a aac -b:a 192k"
    },
    "Compresi贸n M谩xima": {
        "video": "-c:v libx264 -preset veryslow -crf 18",
        "audio": "-c:a aac -b:a 256k"
    }
}

def compress_media(file_path, preset="Compresi贸n Alta", progress=gr.Progress()):
    """Comprimir archivo de media usando FFmpeg"""
    try:
        if not os.path.exists(file_path):
            return None, "Error: Archivo no encontrado"
        
        file_ext = Path(file_path).suffix.lower()
        if file_ext not in SUPPORTED_FORMATS:
            return None, f"Error: Formato {file_ext} no soportado"
        
        # Generar nombre de archivo de salida
        base_name = Path(file_path).stem
        output_path = os.path.join(UPLOADS_DIR, f"{base_name}_compressed{file_ext}")
        
        # Obtener configuraci贸n del preset
        preset_config = COMPRESSION_PRESETS.get(preset, COMPRESSION_PRESETS["Compresi贸n Alta"])
        
        # Construir comando FFmpeg
        cmd = [
            FFMPEG_PATH,
            "-i", file_path,
            "-y",  # Sobrescribir archivo de salida
        ]
        
        # Agregar configuraci贸n seg煤n el tipo de archivo
        if file_ext in VIDEO_FORMATS:
            cmd.extend(preset_config["video"].split())
            cmd.extend(preset_config["audio"].split())
        else:  # Audio
            cmd.extend(preset_config["audio"].split())
        
        cmd.append(output_path)
        
        logger.info(f"Ejecutando comando: {' '.join(cmd)}")
        
        # Ejecutar FFmpeg
        process = subprocess.Popen(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )
        
        # Simular progreso
        for i in progress.tqdm(range(100), desc="Comprimiendo..."):
            time.sleep(0.1)
            if process.poll() is not None:
                break
        
        stdout, stderr = process.communicate()
        
        if process.returncode != 0:
            logger.error(f"Error en FFmpeg: {stderr}")
            return None, f"Error durante compresi贸n: {stderr[:200]}"
        
        if not os.path.exists(output_path):
            return None, "Error: No se pudo crear el archivo comprimido"
        
        # Calcular ratio de compresi贸n
        original_size = os.path.getsize(file_path)
        compressed_size = os.path.getsize(output_path)
        compression_ratio = (1 - compressed_size / original_size) * 100
        
        logger.info(f"Compresi贸n completada. Ratio: {compression_ratio:.1f}%")
        
        return output_path, f"Compresi贸n exitosa! Reducci贸n: {compression_ratio:.1f}%"
        
    except Exception as e:
        logger.error(f"Error en compress_media: {str(e)}")
        return None, f"Error durante compresi贸n: {str(e)}"

def run_app():
    """Ejecutar la aplicaci贸n Gradio"""
    
    # Verificar que FFmpeg existe
    if not os.path.exists(FFMPEG_PATH):
        print(f"Error: FFmpeg no encontrado en {FFMPEG_PATH}")
        return
    
    with gr.Blocks(title="Compresor de Video y Audio", theme=gr.themes.Soft()) as iface:
        gr.Markdown("# 馃幀 Compresor de Video y Audio")
        gr.Markdown("Comprime tus archivos de video y audio de forma eficiente")
        
        with gr.Row():
            with gr.Column():
                file_input = gr.File(
                    label="Seleccionar archivo",
                    file_types=SUPPORTED_FORMATS
                )
                
                preset_dropdown = gr.Dropdown(
                    choices=list(COMPRESSION_PRESETS.keys()),
                    value="Compresi贸n Alta",
                    label="Nivel de compresi贸n"
                )
                
                compress_btn = gr.Button("馃殌 Comprimir", variant="primary")
            
            with gr.Column():
                output_file = gr.File(label="Archivo comprimido")
                status_text = gr.Textbox(label="Estado", interactive=False)
        
        # Informaci贸n sobre formatos soportados
        gr.Markdown(
            f"**Formatos soportados:**\n"
            f"- Video: {', '.join(VIDEO_FORMATS)}\n"
            f"- Audio: {', '.join(AUDIO_FORMATS)}"
        )
        
        # Evento de compresi贸n
        compress_btn.click(
            fn=compress_media,
            inputs=[file_input, preset_dropdown],
            outputs=[output_file, status_text]
        )
    
    # Lanzar interfaz
    iface.launch(
        share=False,
        server_name="127.0.0.1",
        server_port=7862,
        show_error=True,
        inbrowser=True
    )

if __name__ == "__main__":
    run_app()