Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -24,8 +24,8 @@ for file in [INTRO_VIDEO, OUTRO_VIDEO, MUSIC_BG, GLITCH_SOUND, EJEMPLO_VIDEO]:
|
|
24 |
raise FileNotFoundError(f"Falta: {file}")
|
25 |
|
26 |
# Configuración de chunks
|
27 |
-
CHUNK_SIZE = 60 # 1 minuto por chunk
|
28 |
-
MAX_CHUNKS = 50
|
29 |
|
30 |
def eliminar_archivo_tiempo(ruta, delay=1800):
|
31 |
def eliminar():
|
@@ -45,7 +45,7 @@ async def procesar_audio(texto, voz, duracion_video, audio_original):
|
|
45 |
if not texto.strip():
|
46 |
raise ValueError("El texto para TTS no puede estar vacío.")
|
47 |
|
48 |
-
def dividir_texto(texto, max_length=2000):
|
49 |
return [texto[i:i + max_length] for i in range(0, len(texto), max_length)]
|
50 |
|
51 |
fragmentos = dividir_texto(texto)
|
@@ -99,8 +99,8 @@ def aplicar_glitch(video_clip):
|
|
99 |
import numpy as np
|
100 |
frame = frame.copy()
|
101 |
height, width, _ = frame.shape
|
102 |
-
offset = np.random.randint(3, 8)
|
103 |
-
if height > 0:
|
104 |
frame[offset:, :] = np.roll(frame[:-offset, :], -offset, axis=0)
|
105 |
return frame
|
106 |
|
@@ -118,27 +118,31 @@ async def procesar_fragmento(chunk, texto_tts, voz_seleccionada, start_time):
|
|
118 |
audio_original
|
119 |
)
|
120 |
|
121 |
-
segment_duration =
|
122 |
-
overlap =
|
123 |
-
total_segments = int((duracion_chunk) // (segment_duration)) + 1
|
124 |
|
125 |
segments = []
|
126 |
glitch_clips = []
|
127 |
-
glitch_sound = AudioFileClip(GLITCH_SOUND).volumex(0.
|
128 |
|
129 |
current_time = 0
|
130 |
for i in range(total_segments):
|
131 |
-
|
132 |
-
end_time =
|
133 |
-
|
|
|
|
|
|
|
134 |
full_segment = chunk.subclip(current_time, end_time)
|
135 |
|
136 |
-
|
137 |
-
|
|
|
138 |
glitch_part = aplicar_glitch(glitch_part)
|
139 |
processed_segment = concatenate_videoclips([
|
140 |
glitch_part,
|
141 |
-
full_segment.subclip(0.
|
142 |
], method="compose")
|
143 |
|
144 |
glitch_sound_clip = glitch_sound.set_start(start_time + current_time)
|
@@ -147,7 +151,7 @@ async def procesar_fragmento(chunk, texto_tts, voz_seleccionada, start_time):
|
|
147 |
processed_segment = full_segment
|
148 |
|
149 |
segments.append(processed_segment)
|
150 |
-
current_time += segment_duration
|
151 |
|
152 |
video_chunk = concatenate_videoclips(segments, method="compose")
|
153 |
video_chunk = video_chunk.set_audio(audio_final)
|
@@ -167,7 +171,7 @@ async def procesar_fragmento(chunk, texto_tts, voz_seleccionada, start_time):
|
|
167 |
async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
168 |
try:
|
169 |
logging.info("Iniciando procesamiento de video")
|
170 |
-
video_original = VideoFileClip(video_input, target_resolution=(720, 1280))
|
171 |
total_duration = video_original.duration
|
172 |
|
173 |
# Dividir en chunks pequeños
|
@@ -177,7 +181,7 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
|
177 |
chunk = video_original.subclip(start, end)
|
178 |
chunks.append((start, chunk))
|
179 |
|
180 |
-
# Procesar
|
181 |
processed_clips = []
|
182 |
for i, (start_time, chunk) in enumerate(chunks):
|
183 |
logging.info(f"Procesando chunk {i+1}/{len(chunks)}")
|
@@ -187,25 +191,25 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
|
187 |
# Combinar chunks
|
188 |
final_video = concatenate_videoclips(processed_clips, method="compose")
|
189 |
|
190 |
-
# Agregar intro
|
191 |
intro = VideoFileClip(INTRO_VIDEO, target_resolution=(720, 1280))
|
192 |
outro = VideoFileClip(OUTRO_VIDEO, target_resolution=(720, 1280))
|
193 |
final_video = concatenate_videoclips([intro, final_video, outro], method="compose")
|
194 |
|
195 |
-
# Renderizado
|
196 |
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp:
|
197 |
final_video.write_videofile(
|
198 |
tmp.name,
|
199 |
codec="libx264",
|
200 |
audio_codec="aac",
|
201 |
fps=24,
|
202 |
-
threads=2,
|
203 |
-
bitrate="3M",
|
204 |
ffmpeg_params=[
|
205 |
-
"-preset", "
|
206 |
"-crf", "28",
|
207 |
"-movflags", "+faststart",
|
208 |
-
"-vf", "scale=1280:720"
|
209 |
],
|
210 |
verbose=False
|
211 |
)
|
@@ -257,4 +261,4 @@ with gr.Blocks() as demo:
|
|
257 |
)
|
258 |
|
259 |
if __name__ == "__main__":
|
260 |
-
demo.queue().launch()
|
|
|
24 |
raise FileNotFoundError(f"Falta: {file}")
|
25 |
|
26 |
# Configuración de chunks
|
27 |
+
CHUNK_SIZE = 60 # 1 minuto por chunk
|
28 |
+
MAX_CHUNKS = 50
|
29 |
|
30 |
def eliminar_archivo_tiempo(ruta, delay=1800):
|
31 |
def eliminar():
|
|
|
45 |
if not texto.strip():
|
46 |
raise ValueError("El texto para TTS no puede estar vacío.")
|
47 |
|
48 |
+
def dividir_texto(texto, max_length=2000):
|
49 |
return [texto[i:i + max_length] for i in range(0, len(texto), max_length)]
|
50 |
|
51 |
fragmentos = dividir_texto(texto)
|
|
|
99 |
import numpy as np
|
100 |
frame = frame.copy()
|
101 |
height, width, _ = frame.shape
|
102 |
+
offset = np.random.randint(3, 8)
|
103 |
+
if height > 0 and offset != 0:
|
104 |
frame[offset:, :] = np.roll(frame[:-offset, :], -offset, axis=0)
|
105 |
return frame
|
106 |
|
|
|
118 |
audio_original
|
119 |
)
|
120 |
|
121 |
+
segment_duration = 18 # Duración visible del segmento
|
122 |
+
overlap = 2 # Segundos eliminados en cada corte
|
123 |
+
total_segments = int((duracion_chunk - overlap) // (segment_duration - overlap)) + 1
|
124 |
|
125 |
segments = []
|
126 |
glitch_clips = []
|
127 |
+
glitch_sound = AudioFileClip(GLITCH_SOUND).volumex(0.5)
|
128 |
|
129 |
current_time = 0
|
130 |
for i in range(total_segments):
|
131 |
+
# Calcular tiempo final del segmento
|
132 |
+
end_time = current_time + segment_duration
|
133 |
+
if end_time > duracion_chunk:
|
134 |
+
break # ← **Corrección clave**
|
135 |
+
|
136 |
+
# Extraer segmento completo
|
137 |
full_segment = chunk.subclip(current_time, end_time)
|
138 |
|
139 |
+
# Aplicar glitch solo si hay suficiente duración
|
140 |
+
if i > 0 and full_segment.duration >= 0.5: # ← **Validación añadida**
|
141 |
+
glitch_part = full_segment.subclip(0, 0.5)
|
142 |
glitch_part = aplicar_glitch(glitch_part)
|
143 |
processed_segment = concatenate_videoclips([
|
144 |
glitch_part,
|
145 |
+
full_segment.subclip(0.5)
|
146 |
], method="compose")
|
147 |
|
148 |
glitch_sound_clip = glitch_sound.set_start(start_time + current_time)
|
|
|
151 |
processed_segment = full_segment
|
152 |
|
153 |
segments.append(processed_segment)
|
154 |
+
current_time += (segment_duration - overlap) # ← **Ajuste de avance**
|
155 |
|
156 |
video_chunk = concatenate_videoclips(segments, method="compose")
|
157 |
video_chunk = video_chunk.set_audio(audio_final)
|
|
|
171 |
async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
172 |
try:
|
173 |
logging.info("Iniciando procesamiento de video")
|
174 |
+
video_original = VideoFileClip(video_input, target_resolution=(720, 1280))
|
175 |
total_duration = video_original.duration
|
176 |
|
177 |
# Dividir en chunks pequeños
|
|
|
181 |
chunk = video_original.subclip(start, end)
|
182 |
chunks.append((start, chunk))
|
183 |
|
184 |
+
# Procesar cada chunk
|
185 |
processed_clips = []
|
186 |
for i, (start_time, chunk) in enumerate(chunks):
|
187 |
logging.info(f"Procesando chunk {i+1}/{len(chunks)}")
|
|
|
191 |
# Combinar chunks
|
192 |
final_video = concatenate_videoclips(processed_clips, method="compose")
|
193 |
|
194 |
+
# Agregar intro y outro
|
195 |
intro = VideoFileClip(INTRO_VIDEO, target_resolution=(720, 1280))
|
196 |
outro = VideoFileClip(OUTRO_VIDEO, target_resolution=(720, 1280))
|
197 |
final_video = concatenate_videoclips([intro, final_video, outro], method="compose")
|
198 |
|
199 |
+
# Renderizado final
|
200 |
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp:
|
201 |
final_video.write_videofile(
|
202 |
tmp.name,
|
203 |
codec="libx264",
|
204 |
audio_codec="aac",
|
205 |
fps=24,
|
206 |
+
threads=2,
|
207 |
+
bitrate="3M",
|
208 |
ffmpeg_params=[
|
209 |
+
"-preset", "ultrafast",
|
210 |
"-crf", "28",
|
211 |
"-movflags", "+faststart",
|
212 |
+
"-vf", "scale=1280:720"
|
213 |
],
|
214 |
verbose=False
|
215 |
)
|
|
|
261 |
)
|
262 |
|
263 |
if __name__ == "__main__":
|
264 |
+
demo.queue().launch()
|