Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -22,11 +22,11 @@ for file in [INTRO_VIDEO, OUTRO_VIDEO, MUSIC_BG, EJEMPLO_VIDEO]:
|
|
22 |
logging.error(f"Falta archivo necesario: {file}")
|
23 |
raise FileNotFoundError(f"Falta: {file}")
|
24 |
|
25 |
-
# Configuraci贸n de chunks
|
26 |
CHUNK_SIZE = 60 # 1 minuto por chunk
|
27 |
-
SEGMENT_DURATION =
|
28 |
-
TRANSITION_INTERVAL = 30 # Cada cu谩ntos segundos aplicar transici贸n
|
29 |
TRANSITION_DURATION = 1.5 # Duraci贸n del efecto slide
|
|
|
30 |
|
31 |
def eliminar_archivo_tiempo(ruta, delay=1800):
|
32 |
def eliminar():
|
@@ -68,10 +68,12 @@ def crear_musica_fondo(duracion_total):
|
|
68 |
return AudioFileClip(tmp_bg.name).volumex(0.15), tmp_bg.name
|
69 |
|
70 |
def create_slide_transition(clip1, clip2, duration=TRANSITION_DURATION):
|
71 |
-
"""
|
|
|
72 |
part1 = clip1.subclip(clip1.duration - duration)
|
73 |
part2 = clip2.subclip(0, duration)
|
74 |
|
|
|
75 |
transition = CompositeVideoClip([
|
76 |
part1.fx(vfx.fadeout, duration),
|
77 |
part2.fx(vfx.fadein, duration).set_position(
|
@@ -102,7 +104,7 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
|
102 |
audios.append(tts_audio.set_start(0).volumex(0.85))
|
103 |
audio_final = CompositeAudioClip(audios).set_duration(duracion_video)
|
104 |
|
105 |
-
# Dividir video en segmentos con superposici贸n
|
106 |
segments = []
|
107 |
current_time = 0
|
108 |
while current_time < duracion_video:
|
@@ -111,44 +113,22 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada):
|
|
111 |
end_time = duracion_video
|
112 |
segment = video_original.subclip(current_time, end_time)
|
113 |
segments.append(segment)
|
114 |
-
current_time += (SEGMENT_DURATION -
|
115 |
|
116 |
-
# Construir video
|
117 |
clips = []
|
118 |
for i in range(len(segments)):
|
119 |
if i == 0:
|
120 |
clips.append(segments[i])
|
121 |
else:
|
|
|
122 |
transition = create_slide_transition(clips[-1], segments[i])
|
123 |
clips.pop()
|
124 |
clips.append(transition)
|
125 |
-
clips.append(segments[i].subclip(TRANSITION_DURATION))
|
126 |
-
video_base = concatenate_videoclips(clips, method="compose").set_audio(audio_final)
|
127 |
-
|
128 |
-
# Dividir en intervalos de 30 segundos y aplicar transiciones finales
|
129 |
-
parts = []
|
130 |
-
current_time = 0
|
131 |
-
while current_time < video_base.duration:
|
132 |
-
end_time = current_time + TRANSITION_INTERVAL
|
133 |
-
if end_time > video_base.duration:
|
134 |
-
end_time = video_base.duration
|
135 |
-
part = video_base.subclip(current_time, end_time)
|
136 |
-
parts.append(part)
|
137 |
-
current_time = end_time
|
138 |
-
|
139 |
-
# Aplicar transiciones slide cada 30 segundos
|
140 |
-
final_clips = []
|
141 |
-
for i in range(len(parts)):
|
142 |
-
if i == 0:
|
143 |
-
final_clips.append(parts[i])
|
144 |
-
else:
|
145 |
-
transition = create_slide_transition(final_clips[-1], parts[i])
|
146 |
-
final_clips.pop()
|
147 |
-
final_clips.append(transition)
|
148 |
-
final_clips.append(parts[i])
|
149 |
|
150 |
# Combinar todo
|
151 |
-
video_final = concatenate_videoclips(
|
152 |
|
153 |
# Agregar intro y outro
|
154 |
intro = VideoFileClip(INTRO_VIDEO, target_resolution=(720, 1280))
|
|
|
22 |
logging.error(f"Falta archivo necesario: {file}")
|
23 |
raise FileNotFoundError(f"Falta: {file}")
|
24 |
|
25 |
+
# Configuraci贸n de chunks (Modificada para 30 segundos)
|
26 |
CHUNK_SIZE = 60 # 1 minuto por chunk
|
27 |
+
SEGMENT_DURATION = 31.5 # 30 segundos de contenido + 1.5 de transici贸n
|
|
|
28 |
TRANSITION_DURATION = 1.5 # Duraci贸n del efecto slide
|
29 |
+
OVERLAP = TRANSITION_DURATION # El overlap es igual a la duraci贸n de la transici贸n
|
30 |
|
31 |
def eliminar_archivo_tiempo(ruta, delay=1800):
|
32 |
def eliminar():
|
|
|
68 |
return AudioFileClip(tmp_bg.name).volumex(0.15), tmp_bg.name
|
69 |
|
70 |
def create_slide_transition(clip1, clip2, duration=TRANSITION_DURATION):
|
71 |
+
"""Transici贸n slide con movimiento m谩s pronunciado"""
|
72 |
+
# Tomar la 煤ltima parte del clip1 y la primera parte del clip2
|
73 |
part1 = clip1.subclip(clip1.duration - duration)
|
74 |
part2 = clip2.subclip(0, duration)
|
75 |
|
76 |
+
# Crear animaci贸n de deslizamiento
|
77 |
transition = CompositeVideoClip([
|
78 |
part1.fx(vfx.fadeout, duration),
|
79 |
part2.fx(vfx.fadein, duration).set_position(
|
|
|
104 |
audios.append(tts_audio.set_start(0).volumex(0.85))
|
105 |
audio_final = CompositeAudioClip(audios).set_duration(duracion_video)
|
106 |
|
107 |
+
# Dividir video en segmentos con superposici贸n controlada
|
108 |
segments = []
|
109 |
current_time = 0
|
110 |
while current_time < duracion_video:
|
|
|
113 |
end_time = duracion_video
|
114 |
segment = video_original.subclip(current_time, end_time)
|
115 |
segments.append(segment)
|
116 |
+
current_time += (SEGMENT_DURATION - OVERLAP) # Avance considerando el overlap
|
117 |
|
118 |
+
# Construir video con transiciones
|
119 |
clips = []
|
120 |
for i in range(len(segments)):
|
121 |
if i == 0:
|
122 |
clips.append(segments[i])
|
123 |
else:
|
124 |
+
# Crear transici贸n entre el final del clip anterior y el inicio del actual
|
125 |
transition = create_slide_transition(clips[-1], segments[i])
|
126 |
clips.pop()
|
127 |
clips.append(transition)
|
128 |
+
clips.append(segments[i].subclip(TRANSITION_DURATION)) # Eliminar parte ya usada en transici贸n
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
|
130 |
# Combinar todo
|
131 |
+
video_final = concatenate_videoclips(clips, method="compose").set_audio(audio_final)
|
132 |
|
133 |
# Agregar intro y outro
|
134 |
intro = VideoFileClip(INTRO_VIDEO, target_resolution=(720, 1280))
|