Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -104,4 +104,90 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
|
| 104 |
segments.append(full_segment)
|
| 105 |
current_time += (SEGMENT_DURATION - OVERLAP)
|
| 106 |
|
| 107 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
segments.append(full_segment)
|
| 105 |
current_time += (SEGMENT_DURATION - OVERLAP)
|
| 106 |
|
| 107 |
+
# Asegurar que haya al menos un segmento
|
| 108 |
+
if not segments:
|
| 109 |
+
logging.warning("Video demasiado corto, devolviendo el video original.")
|
| 110 |
+
video_final = video_original.set_audio(audio_final)
|
| 111 |
+
else:
|
| 112 |
+
video_final = concatenate_videoclips(segments, method="compose")
|
| 113 |
+
video_final = video_final.set_audio(audio_final)
|
| 114 |
+
|
| 115 |
+
# Agregar intro y outro
|
| 116 |
+
intro = VideoFileClip(INTRO_VIDEO, target_resolution=(720, 1280))
|
| 117 |
+
outro = VideoFileClip(OUTRO_VIDEO, target_resolution=(720, 1280))
|
| 118 |
+
video_final = concatenate_videoclips([intro, video_final, outro], method="compose")
|
| 119 |
+
|
| 120 |
+
# Renderizado final
|
| 121 |
+
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp:
|
| 122 |
+
video_final.write_videofile(
|
| 123 |
+
tmp.name,
|
| 124 |
+
codec="libx264",
|
| 125 |
+
audio_codec="aac",
|
| 126 |
+
fps=24,
|
| 127 |
+
threads=2,
|
| 128 |
+
bitrate="3M",
|
| 129 |
+
ffmpeg_params=[
|
| 130 |
+
"-preset", "ultrafast",
|
| 131 |
+
"-crf", "28",
|
| 132 |
+
"-movflags", "+faststart",
|
| 133 |
+
"-vf", "scale=1280:720"
|
| 134 |
+
],
|
| 135 |
+
verbose=False
|
| 136 |
+
)
|
| 137 |
+
eliminar_archivo_tiempo(tmp.name, 1800)
|
| 138 |
+
logging.info(f"Video final guardado: {tmp.name}")
|
| 139 |
+
return tmp.name
|
| 140 |
+
|
| 141 |
+
except Exception as e:
|
| 142 |
+
logging.error(f"Fallo general: {str(e)}")
|
| 143 |
+
raise
|
| 144 |
+
finally:
|
| 145 |
+
try:
|
| 146 |
+
if video_original:
|
| 147 |
+
video_original.close()
|
| 148 |
+
if intro:
|
| 149 |
+
intro.close()
|
| 150 |
+
if outro:
|
| 151 |
+
outro.close()
|
| 152 |
+
for file in temp_files:
|
| 153 |
+
try:
|
| 154 |
+
os.remove(file)
|
| 155 |
+
except Exception as e:
|
| 156 |
+
logging.warning(f"Error limpiando {file}: {e}")
|
| 157 |
+
except Exception as e:
|
| 158 |
+
logging.warning(f"Error al cerrar recursos: {str(e)}")
|
| 159 |
+
|
| 160 |
+
# Interfaz Gradio
|
| 161 |
+
with gr.Blocks() as demo:
|
| 162 |
+
gr.Markdown("# Editor de Video con IA")
|
| 163 |
+
|
| 164 |
+
with gr.Tab("Principal"):
|
| 165 |
+
video_input = gr.Video(label="Subir video")
|
| 166 |
+
texto_tts = gr.Textbox(
|
| 167 |
+
label="Texto para TTS",
|
| 168 |
+
lines=3,
|
| 169 |
+
placeholder="Escribe aquí tu texto..."
|
| 170 |
+
)
|
| 171 |
+
voz_seleccionada = gr.Dropdown(
|
| 172 |
+
label="Voz",
|
| 173 |
+
choices=["es-ES-AlvaroNeural", "es-MX-BeatrizNeural"],
|
| 174 |
+
value="es-ES-AlvaroNeural"
|
| 175 |
+
)
|
| 176 |
+
procesar_btn = gr.Button("Generar Video")
|
| 177 |
+
video_output = gr.Video(label="Video Procesado")
|
| 178 |
+
|
| 179 |
+
with gr.Accordion("Ejemplos de Uso", open=False):
|
| 180 |
+
gr.Examples(
|
| 181 |
+
examples=[[EJEMPLO_VIDEO, "¡Hola! Esto es una prueba. Suscríbete al canal."]],
|
| 182 |
+
inputs=[video_input, texto_tts],
|
| 183 |
+
label="Ejemplos"
|
| 184 |
+
)
|
| 185 |
+
|
| 186 |
+
procesar_btn.click(
|
| 187 |
+
procesar_video,
|
| 188 |
+
inputs=[video_input, texto_tts, voz_seleccionada],
|
| 189 |
+
outputs=video_output
|
| 190 |
+
)
|
| 191 |
+
|
| 192 |
+
if __name__ == "__main__":
|
| 193 |
+
demo.queue().launch()
|