Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -23,16 +23,20 @@ for file in [INTRO_VIDEO, OUTRO_VIDEO, MUSIC_BG, GLITCH_SOUND, EJEMPLO_VIDEO]:
|
|
23 |
logging.error(f"Falta archivo necesario: {file}")
|
24 |
raise FileNotFoundError(f"Falta: {file}")
|
25 |
|
26 |
-
def eliminar_archivo_tiempo(ruta):
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
|
|
|
|
|
|
|
|
36 |
|
37 |
async def procesar_audio(texto, voz, duracion_video, audio_original):
|
38 |
temp_files = []
|
@@ -92,7 +96,7 @@ def aplicar_glitch(video_clip):
|
|
92 |
"""Versión corregida del efecto glitch"""
|
93 |
def glitch_effect(frame):
|
94 |
import numpy as np
|
95 |
-
frame = frame.copy()
|
96 |
height, width, _ = frame.shape
|
97 |
offset = np.random.randint(-5, 5)
|
98 |
|
@@ -112,13 +116,11 @@ def aplicar_glitch(video_clip):
|
|
112 |
|
113 |
async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
114 |
try:
|
115 |
-
# Carga optimizada con control de memoria
|
116 |
intro = VideoFileClip(INTRO_VIDEO, target_resolution=(1080, 1920))
|
117 |
outro = VideoFileClip(OUTRO_VIDEO, target_resolution=(1080, 1920))
|
118 |
video_original = VideoFileClip(video_input, target_resolution=(1080, 1920))
|
119 |
audio_original = video_original.audio
|
120 |
|
121 |
-
# Liberar recursos inmediatamente
|
122 |
intro.reader.close()
|
123 |
outro.reader.close()
|
124 |
video_original.reader.close()
|
@@ -147,7 +149,6 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
|
147 |
|
148 |
segment = video_original.subclip(start_time, end_time)
|
149 |
|
150 |
-
# Aplicar glitch solo en segmentos válidos
|
151 |
if i % 2 == 0 and i > 0 and (end_time - start_time) > 0.5:
|
152 |
glitch_segment = aplicar_glitch(segment.subclip(0, 0.3))
|
153 |
glitch_sound_clip = glitch_sound.set_start(start_time)
|
@@ -161,18 +162,16 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
|
161 |
audio_final = CompositeAudioClip([audio_final] + glitch_clips).set_duration(video_final.duration)
|
162 |
video_con_audio = video_final.set_audio(audio_final)
|
163 |
|
164 |
-
# Recargar intro/outro para evitar conflictos de memoria
|
165 |
intro = VideoFileClip(INTRO_VIDEO, target_resolution=(1080, 1920))
|
166 |
outro = VideoFileClip(OUTRO_VIDEO, target_resolution=(1080, 1920))
|
167 |
video_final = concatenate_videoclips([intro, video_con_audio, outro], method="compose")
|
168 |
|
169 |
-
# Renderizado optimizado
|
170 |
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp:
|
171 |
video_final.write_videofile(
|
172 |
tmp.name,
|
173 |
codec="libx264",
|
174 |
audio_codec="aac",
|
175 |
-
fps=24,
|
176 |
threads=4,
|
177 |
bitrate="5M",
|
178 |
ffmpeg_params=[
|
@@ -183,14 +182,13 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
|
183 |
],
|
184 |
verbose=False
|
185 |
)
|
186 |
-
eliminar_archivo_tiempo(tmp.name)
|
187 |
return tmp.name
|
188 |
|
189 |
except Exception as e:
|
190 |
logging.error(f" fallo general: {str(e)}")
|
191 |
raise
|
192 |
finally:
|
193 |
-
# Forzar cierre de recursos
|
194 |
try:
|
195 |
intro.close()
|
196 |
outro.close()
|
|
|
23 |
logging.error(f"Falta archivo necesario: {file}")
|
24 |
raise FileNotFoundError(f"Falta: {file}")
|
25 |
|
26 |
+
def eliminar_archivo_tiempo(ruta, delay=1800):
|
27 |
+
"""Elimina el archivo después de 'delay' segundos (30 minutos por defecto)"""
|
28 |
+
def eliminar():
|
29 |
+
try:
|
30 |
+
if os.path.exists(ruta):
|
31 |
+
os.remove(ruta)
|
32 |
+
logging.info(f"Archivo eliminado: {ruta}")
|
33 |
+
except Exception as e:
|
34 |
+
logging.error(f"Error al eliminar {ruta}: {e}")
|
35 |
+
finally:
|
36 |
+
import gc
|
37 |
+
gc.collect()
|
38 |
+
from threading import Timer
|
39 |
+
Timer(delay, eliminar).start() # ← Timer restaurado con 30 minutos de espera
|
40 |
|
41 |
async def procesar_audio(texto, voz, duracion_video, audio_original):
|
42 |
temp_files = []
|
|
|
96 |
"""Versión corregida del efecto glitch"""
|
97 |
def glitch_effect(frame):
|
98 |
import numpy as np
|
99 |
+
frame = frame.copy()
|
100 |
height, width, _ = frame.shape
|
101 |
offset = np.random.randint(-5, 5)
|
102 |
|
|
|
116 |
|
117 |
async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
118 |
try:
|
|
|
119 |
intro = VideoFileClip(INTRO_VIDEO, target_resolution=(1080, 1920))
|
120 |
outro = VideoFileClip(OUTRO_VIDEO, target_resolution=(1080, 1920))
|
121 |
video_original = VideoFileClip(video_input, target_resolution=(1080, 1920))
|
122 |
audio_original = video_original.audio
|
123 |
|
|
|
124 |
intro.reader.close()
|
125 |
outro.reader.close()
|
126 |
video_original.reader.close()
|
|
|
149 |
|
150 |
segment = video_original.subclip(start_time, end_time)
|
151 |
|
|
|
152 |
if i % 2 == 0 and i > 0 and (end_time - start_time) > 0.5:
|
153 |
glitch_segment = aplicar_glitch(segment.subclip(0, 0.3))
|
154 |
glitch_sound_clip = glitch_sound.set_start(start_time)
|
|
|
162 |
audio_final = CompositeAudioClip([audio_final] + glitch_clips).set_duration(video_final.duration)
|
163 |
video_con_audio = video_final.set_audio(audio_final)
|
164 |
|
|
|
165 |
intro = VideoFileClip(INTRO_VIDEO, target_resolution=(1080, 1920))
|
166 |
outro = VideoFileClip(OUTRO_VIDEO, target_resolution=(1080, 1920))
|
167 |
video_final = concatenate_videoclips([intro, video_con_audio, outro], method="compose")
|
168 |
|
|
|
169 |
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp:
|
170 |
video_final.write_videofile(
|
171 |
tmp.name,
|
172 |
codec="libx264",
|
173 |
audio_codec="aac",
|
174 |
+
fps=24,
|
175 |
threads=4,
|
176 |
bitrate="5M",
|
177 |
ffmpeg_params=[
|
|
|
182 |
],
|
183 |
verbose=False
|
184 |
)
|
185 |
+
eliminar_archivo_tiempo(tmp.name, 1800) # ← Ahora se eliminan a los 30 minutos
|
186 |
return tmp.name
|
187 |
|
188 |
except Exception as e:
|
189 |
logging.error(f" fallo general: {str(e)}")
|
190 |
raise
|
191 |
finally:
|
|
|
192 |
try:
|
193 |
intro.close()
|
194 |
outro.close()
|