gnosticdev commited on
Commit
2da8de0
verified
1 Parent(s): 9f53b36

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +20 -12
app.py CHANGED
@@ -18,6 +18,9 @@ OUTRO_VIDEO = "outrovideo.mp4"
18
  MUSIC_BG = "musicafondo.mp3"
19
  EJEMPLO_VIDEO = "ejemplo.mp4"
20
 
 
 
 
21
  # Configuraci贸n de chunks
22
  SEGMENT_DURATION = 30 # Duraci贸n exacta entre transiciones (sin overlap)
23
  TRANSITION_DURATION = 1.5 # Duraci贸n del efecto slide
@@ -68,13 +71,13 @@ def convertir_video(video_path):
68
  with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_converted:
69
  output_path = tmp_converted.name
70
 
71
- # Convertir a un formato m谩s eficiente y con menor resoluci贸n para optimizar
72
- os.system(f'ffmpeg -i "{video_path}" -vf "scale={MAX_RESOLUTION[0]}:{MAX_RESOLUTION[1]}" -c:v libx264 -crf 28 -preset ultrafast -c:a aac -b:a 96k "{output_path}" -y')
73
 
74
  # Comprobar si ahora cumple las limitaciones de tama帽o
75
  if not validar_video(output_path):
76
- # Si sigue sin cumplir, aumentar la compresi贸n
77
- os.system(f'ffmpeg -i "{output_path}" -vf "scale={MAX_RESOLUTION[0]}:{MAX_RESOLUTION[1]}" -c:v libx264 -crf 32 -preset ultrafast -c:a aac -b:a 64k "{output_path}.tmp" -y')
78
  os.remove(output_path)
79
  os.rename(f"{output_path}.tmp", output_path)
80
 
@@ -115,14 +118,17 @@ def crear_musica_fondo(duracion_total):
115
  return AudioFileClip(tmp_bg.name).volumex(0.15), tmp_bg.name
116
 
117
  def create_slide_transition(clip1, clip2, duration=TRANSITION_DURATION):
 
 
 
118
  part1 = clip1.subclip(clip1.duration - duration)
119
  part2 = clip2.subclip(0, duration)
120
  transition = CompositeVideoClip([
121
  part1.fx(vfx.fadeout, duration),
122
  part2.fx(vfx.fadein, duration).set_position(
123
- lambda t: ('center', MAX_RESOLUTION[1] - (MAX_RESOLUTION[1] * (t/duration)))
124
  )
125
- ], size=MAX_RESOLUTION).set_duration(duration) # Reducido para optimizar
126
  return transition
127
 
128
  def liberar_memoria(objetos_cerrar=None):
@@ -155,13 +161,16 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada, progress=gr.P
155
  temp_files.append(video_input)
156
 
157
  progress(0.1, desc="Preparando video")
158
- # Reducir resoluci贸n para optimizar procesamiento
159
  video_original = VideoFileClip(video_input)
160
  duracion_video = video_original.duration
 
 
161
  video_original.close() # Cerrar para liberar memoria
162
 
163
  # Informaci贸n importante sobre el video original
164
  logging.info(f"Duraci贸n total del video: {duracion_video} segundos")
 
165
 
166
  if duracion_video <= 0:
167
  raise ValueError("El video debe tener una duraci贸n mayor que cero.")
@@ -189,7 +198,6 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada, progress=gr.P
189
  chunk_video = VideoFileClip(video_input).subclip(chunk_start, chunk_end)
190
 
191
  # Extraer la porci贸n de audio correspondiente a este bloque
192
- # FIX: Correcci贸n para evitar acceder a tiempo m谩s all谩 de la duraci贸n del audio TTS
193
  tts_chunk_end = min(chunk_end, tts_audio.duration)
194
  chunk_tts = None
195
  if chunk_start < tts_audio.duration:
@@ -258,9 +266,9 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada, progress=gr.P
258
  liberar_memoria([tts_audio, bg_audio])
259
  tts_audio = bg_audio = None
260
 
261
- # A帽adir intro y outro
262
  progress(0.85, desc="Preparando intro y outro")
263
- intro = VideoFileClip(INTRO_VIDEO, target_resolution=MAX_RESOLUTION)
264
  with tempfile.NamedTemporaryFile(delete=False, suffix="_intro.mp4") as tmp_intro:
265
  intro.write_videofile(
266
  tmp_intro.name,
@@ -274,7 +282,7 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada, progress=gr.P
274
  segmentos_temp.insert(0, tmp_intro.name) # Intro al principio
275
  intro.close()
276
 
277
- outro = VideoFileClip(OUTRO_VIDEO, target_resolution=MAX_RESOLUTION)
278
  with tempfile.NamedTemporaryFile(delete=False, suffix="_outro.mp4") as tmp_outro:
279
  outro.write_videofile(
280
  tmp_outro.name,
@@ -415,7 +423,7 @@ with gr.Blocks() as demo:
415
  - **Optimizaciones para Hugging Face Spaces:**
416
  - Procesamiento por bloques para videos largos
417
  - M谩ximo tama帽o de archivo: 200MB
418
- - Resoluci贸n reducida a 640x360 para procesamiento m谩s r谩pido
419
  - Texto TTS limitado a 1000 caracteres
420
  - Las transiciones ocurren cada 30 segundos
421
  - El video contiene intro y outro predefinidos
 
18
  MUSIC_BG = "musicafondo.mp3"
19
  EJEMPLO_VIDEO = "ejemplo.mp4"
20
 
21
+ # CONSTANTES DE LIMITACIONES
22
+ MAX_VIDEO_SIZE = 200 * 1024 * 1024 # Tama帽o m谩ximo en bytes (200MB)
23
+
24
  # Configuraci贸n de chunks
25
  SEGMENT_DURATION = 30 # Duraci贸n exacta entre transiciones (sin overlap)
26
  TRANSITION_DURATION = 1.5 # Duraci贸n del efecto slide
 
71
  with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp_converted:
72
  output_path = tmp_converted.name
73
 
74
+ # Convertir a un formato m谩s eficiente pero manteniendo la resoluci贸n original
75
+ os.system(f'ffmpeg -i "{video_path}" -c:v libx264 -crf 28 -preset ultrafast -c:a aac -b:a 96k "{output_path}" -y')
76
 
77
  # Comprobar si ahora cumple las limitaciones de tama帽o
78
  if not validar_video(output_path):
79
+ # Si sigue sin cumplir, aumentar la compresi贸n pero sin cambiar la resoluci贸n
80
+ os.system(f'ffmpeg -i "{output_path}" -c:v libx264 -crf 32 -preset ultrafast -c:a aac -b:a 64k "{output_path}.tmp" -y')
81
  os.remove(output_path)
82
  os.rename(f"{output_path}.tmp", output_path)
83
 
 
118
  return AudioFileClip(tmp_bg.name).volumex(0.15), tmp_bg.name
119
 
120
  def create_slide_transition(clip1, clip2, duration=TRANSITION_DURATION):
121
+ # Obtener dimensiones de los clips
122
+ width, height = clip1.size
123
+
124
  part1 = clip1.subclip(clip1.duration - duration)
125
  part2 = clip2.subclip(0, duration)
126
  transition = CompositeVideoClip([
127
  part1.fx(vfx.fadeout, duration),
128
  part2.fx(vfx.fadein, duration).set_position(
129
+ lambda t: ('center', height - (height * (t/duration)))
130
  )
131
+ ], size=(width, height)).set_duration(duration)
132
  return transition
133
 
134
  def liberar_memoria(objetos_cerrar=None):
 
161
  temp_files.append(video_input)
162
 
163
  progress(0.1, desc="Preparando video")
164
+ # Cargamos el video original pero respetamos su resoluci贸n
165
  video_original = VideoFileClip(video_input)
166
  duracion_video = video_original.duration
167
+ # Guardamos las dimensiones originales
168
+ original_size = video_original.size
169
  video_original.close() # Cerrar para liberar memoria
170
 
171
  # Informaci贸n importante sobre el video original
172
  logging.info(f"Duraci贸n total del video: {duracion_video} segundos")
173
+ logging.info(f"Resoluci贸n original: {original_size[0]}x{original_size[1]}")
174
 
175
  if duracion_video <= 0:
176
  raise ValueError("El video debe tener una duraci贸n mayor que cero.")
 
198
  chunk_video = VideoFileClip(video_input).subclip(chunk_start, chunk_end)
199
 
200
  # Extraer la porci贸n de audio correspondiente a este bloque
 
201
  tts_chunk_end = min(chunk_end, tts_audio.duration)
202
  chunk_tts = None
203
  if chunk_start < tts_audio.duration:
 
266
  liberar_memoria([tts_audio, bg_audio])
267
  tts_audio = bg_audio = None
268
 
269
+ # A帽adir intro y outro - conservar resoluci贸n original para consistencia
270
  progress(0.85, desc="Preparando intro y outro")
271
+ intro = VideoFileClip(INTRO_VIDEO)
272
  with tempfile.NamedTemporaryFile(delete=False, suffix="_intro.mp4") as tmp_intro:
273
  intro.write_videofile(
274
  tmp_intro.name,
 
282
  segmentos_temp.insert(0, tmp_intro.name) # Intro al principio
283
  intro.close()
284
 
285
+ outro = VideoFileClip(OUTRO_VIDEO)
286
  with tempfile.NamedTemporaryFile(delete=False, suffix="_outro.mp4") as tmp_outro:
287
  outro.write_videofile(
288
  tmp_outro.name,
 
423
  - **Optimizaciones para Hugging Face Spaces:**
424
  - Procesamiento por bloques para videos largos
425
  - M谩ximo tama帽o de archivo: 200MB
426
+ - Mantiene la resoluci贸n original del video
427
  - Texto TTS limitado a 1000 caracteres
428
  - Las transiciones ocurren cada 30 segundos
429
  - El video contiene intro y outro predefinidos