gnosticdev commited on
Commit
e098d46
·
verified ·
1 Parent(s): e9b7708

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -39
app.py CHANGED
@@ -9,7 +9,7 @@ import gradio as gr
9
  import torch
10
  from transformers import GPT2Tokenizer, GPT2LMHeadModel
11
  from keybert import KeyBERT
12
- # CORRECCIÓN CRÍTICA DEFINITIVA DEL TYPO DE IMPORTACIÓN
13
  from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip, concatenate_audioclips, AudioClip
14
  import re
15
  import math
@@ -176,7 +176,7 @@ def generate_script(prompt, max_length=150):
176
  return prompt.strip()
177
 
178
  # Función TTS con voz especificada
179
- async def text_to_speech(text, output_path, voice): # voice is now a parameter
180
  logger.info(f"Convirtiendo texto a voz | Caracteres: {len(text)} | Voz: {voice} | Salida: {output_path}")
181
  if not text or not text.strip():
182
  logger.warning("Texto vacío para TTS")
@@ -708,10 +708,9 @@ def crear_video(prompt_type, input_text, musica_file=None):
708
 
709
 
710
  if musica_audio_looped:
711
- # Usar la música loopeada y el audio TTS original para la composición
712
  composite_audio = CompositeAudioClip([
713
- musica_audio_looped.volumex(0.2), # Volumen 20% para música
714
- audio_tts_original.volumex(1.0) # Volumen 100% para voz
715
  ])
716
 
717
  if composite_audio.duration is None or composite_audio.duration <= 0:
@@ -722,7 +721,7 @@ def crear_video(prompt_type, input_text, musica_file=None):
722
  else:
723
  logger.info("Mezcla de audio completada (voz + música).")
724
  final_audio = composite_audio
725
- musica_audio = musica_audio_looped # Asignar para limpieza
726
 
727
  except Exception as e:
728
  logger.warning(f"Error procesando música de fondo: {str(e)}", exc_info=True)
@@ -797,7 +796,7 @@ def crear_video(prompt_type, input_text, musica_file=None):
797
  except Exception as e:
798
  logger.warning(f"Error cerrando segmento de video en finally: {str(e)}")
799
 
800
- if musica_audio is not None: # musica_audio holds the potentially looped clip
801
  try:
802
  musica_audio.close()
803
  except Exception as e:
@@ -848,12 +847,12 @@ def crear_video(prompt_type, input_text, musica_file=None):
848
  logger.info(f"Directorio temporal intermedio {temp_dir_intermediate} persistirá para que Gradio lea el video final.")
849
 
850
 
851
- # CAMBIO CRÍTICO: run_app ahora toma 4 argumentos
852
  def run_app(prompt_type, prompt_ia, prompt_manual, musica_file):
853
  logger.info("="*80)
854
  logger.info("SOLICITUD RECIBIDA EN INTERFAZ")
855
 
856
- # La lógica para elegir el texto de entrada YA ESTÁ AQUÍ
857
  input_text = prompt_ia if prompt_type == "Generar Guion con IA" else prompt_manual
858
 
859
  output_video = None
@@ -914,26 +913,24 @@ with gr.Blocks(title="Generador de Videos con IA", theme=gr.themes.Soft(), css="
914
  value="Generar Guion con IA"
915
  )
916
 
917
- # Estos inputs siempre se pasan a run_app, independientemente de cuál se use
918
- prompt_ia = gr.Textbox(
919
- label="Tema para IA",
920
- lines=2,
921
- placeholder="Ej: Un paisaje natural con montañas y ríos al amanecer...",
922
- max_lines=4,
923
- value="",
924
- # Hacer visible/oculto por el evento change
925
- visible=True
926
- )
927
-
928
- prompt_manual = gr.Textbox(
929
- label="Tu Guion Completo",
930
- lines=5,
931
- placeholder="Ej: En este video exploraremos los misterios del océano...",
932
- max_lines=10,
933
- value="",
934
- # Hacer visible/oculto por el evento change
935
- visible=False # Oculto por defecto
936
- )
937
 
938
  musica_input = gr.Audio(
939
  label="Música de fondo (opcional)",
@@ -963,13 +960,13 @@ with gr.Blocks(title="Generador de Videos con IA", theme=gr.themes.Soft(), css="
963
  value="Esperando entrada..."
964
  )
965
 
966
- # Evento para mostrar/ocultar los campos de texto según el tipo de prompt
967
- # Ahora usamos las Columnas para controlar la visibilidad
968
  prompt_type.change(
969
  lambda x: (gr.update(visible=x == "Generar Guion con IA"),
970
  gr.update(visible=x == "Usar Mi Guion")),
971
  inputs=prompt_type,
972
- outputs=[prompt_ia.parent, prompt_manual.parent] # Apuntar a las Columnas padre
 
973
  )
974
 
975
  # Evento click del botón de generar video
@@ -977,19 +974,18 @@ with gr.Blocks(title="Generador de Videos con IA", theme=gr.themes.Soft(), css="
977
  # Acción 1 (síncrona): Resetear salidas y establecer estado a procesando
978
  lambda: (None, None, gr.update(value="⏳ Procesando... Esto puede tomar 2-5 minutos o más para videos largos.", interactive=False)),
979
  outputs=[video_output, file_output, status_output],
980
- queue=True, # Usar la cola de Gradio para tareas largas
981
  ).then(
982
  # Acción 2 (asíncrona): Llamar a la función principal de procesamiento
983
  run_app,
984
  # CAMBIO CRÍTICO: Pasar los 4 argumentos definidos por run_app
985
  inputs=[prompt_type, prompt_ia, prompt_manual, musica_input],
986
- outputs=[video_output, file_output, status_output] # Coincidir las 3 salidas de run_app
987
  ).then(
988
  # Acción 3 (síncrona): Hacer visible el enlace de descarga si se retornó un archivo
989
- # Verificar si file_output tiene un valor (el path)
990
  lambda video_path, file_path: gr.update(visible=file_path is not None),
991
- inputs=[video_output, file_output], # Usar ambas salidas como entrada para esta función
992
- outputs=[file_output] # Actualizar visibilidad del componente file_output
993
  )
994
 
995
 
@@ -1024,8 +1020,6 @@ if __name__ == "__main__":
1024
 
1025
  logger.info("Iniciando aplicación Gradio...")
1026
  try:
1027
- # Gradio Queue maneja tareas largas, no es necesario un ajuste global de timeout aquí.
1028
- # El timeout se gestiona por solicitud o por el límite del worker de la cola.
1029
  app.launch(server_name="0.0.0.0", server_port=7860, share=False)
1030
  except Exception as e:
1031
  logger.critical(f"No se pudo iniciar la app: {str(e)}", exc_info=True)
 
9
  import torch
10
  from transformers import GPT2Tokenizer, GPT2LMHeadModel
11
  from keybert import KeyBERT
12
+ # CORRECCIÓN CRÍTICA DEFINITIVA: Eliminar 'concatenate_videoclip' (singular) de la importación
13
  from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip, concatenate_audioclips, AudioClip
14
  import re
15
  import math
 
176
  return prompt.strip()
177
 
178
  # Función TTS con voz especificada
179
+ async def text_to_speech(text, output_path, voice):
180
  logger.info(f"Convirtiendo texto a voz | Caracteres: {len(text)} | Voz: {voice} | Salida: {output_path}")
181
  if not text or not text.strip():
182
  logger.warning("Texto vacío para TTS")
 
708
 
709
 
710
  if musica_audio_looped:
 
711
  composite_audio = CompositeAudioClip([
712
+ musica_audio_looped.volumex(0.2),
713
+ audio_tts_original.volumex(1.0)
714
  ])
715
 
716
  if composite_audio.duration is None or composite_audio.duration <= 0:
 
721
  else:
722
  logger.info("Mezcla de audio completada (voz + música).")
723
  final_audio = composite_audio
724
+ musica_audio = musica_audio_looped
725
 
726
  except Exception as e:
727
  logger.warning(f"Error procesando música de fondo: {str(e)}", exc_info=True)
 
796
  except Exception as e:
797
  logger.warning(f"Error cerrando segmento de video en finally: {str(e)}")
798
 
799
+ if musica_audio is not None:
800
  try:
801
  musica_audio.close()
802
  except Exception as e:
 
847
  logger.info(f"Directorio temporal intermedio {temp_dir_intermediate} persistirá para que Gradio lea el video final.")
848
 
849
 
850
+ # CAMBIO CRÍTICO: run_app define 4 argumentos
851
  def run_app(prompt_type, prompt_ia, prompt_manual, musica_file):
852
  logger.info("="*80)
853
  logger.info("SOLICITUD RECIBIDA EN INTERFAZ")
854
 
855
+ # La lógica para elegir el texto de entrada YA ESTÁ AQUÍ y funciona con ambos inputs pasados
856
  input_text = prompt_ia if prompt_type == "Generar Guion con IA" else prompt_manual
857
 
858
  output_video = None
 
913
  value="Generar Guion con IA"
914
  )
915
 
916
+ # Contenedores para los campos de texto para controlar la visibilidad
917
+ with gr.Column(visible=True) as ia_guion_column:
918
+ prompt_ia = gr.Textbox(
919
+ label="Tema para IA",
920
+ lines=2,
921
+ placeholder="Ej: Un paisaje natural con montañas y ríos al amanecer...",
922
+ max_lines=4,
923
+ value=""
924
+ )
925
+
926
+ with gr.Column(visible=False) as manual_guion_column:
927
+ prompt_manual = gr.Textbox(
928
+ label="Tu Guion Completo",
929
+ lines=5,
930
+ placeholder="Ej: En este video exploraremos los misterios del océano...",
931
+ max_lines=10,
932
+ value=""
933
+ )
 
 
934
 
935
  musica_input = gr.Audio(
936
  label="Música de fondo (opcional)",
 
960
  value="Esperando entrada..."
961
  )
962
 
963
+ # CAMBIO CRÍTICO: Controlar la visibilidad de las COLUMNAS contenedoras
 
964
  prompt_type.change(
965
  lambda x: (gr.update(visible=x == "Generar Guion con IA"),
966
  gr.update(visible=x == "Usar Mi Guion")),
967
  inputs=prompt_type,
968
+ # Apuntar a los componentes Column padre
969
+ outputs=[ia_guion_column, manual_guion_column]
970
  )
971
 
972
  # Evento click del botón de generar video
 
974
  # Acción 1 (síncrona): Resetear salidas y establecer estado a procesando
975
  lambda: (None, None, gr.update(value="⏳ Procesando... Esto puede tomar 2-5 minutos o más para videos largos.", interactive=False)),
976
  outputs=[video_output, file_output, status_output],
977
+ queue=True,
978
  ).then(
979
  # Acción 2 (asíncrona): Llamar a la función principal de procesamiento
980
  run_app,
981
  # CAMBIO CRÍTICO: Pasar los 4 argumentos definidos por run_app
982
  inputs=[prompt_type, prompt_ia, prompt_manual, musica_input],
983
+ outputs=[video_output, file_output, status_output]
984
  ).then(
985
  # Acción 3 (síncrona): Hacer visible el enlace de descarga si se retornó un archivo
 
986
  lambda video_path, file_path: gr.update(visible=file_path is not None),
987
+ inputs=[video_output, file_output],
988
+ outputs=[file_output]
989
  )
990
 
991
 
 
1020
 
1021
  logger.info("Iniciando aplicación Gradio...")
1022
  try:
 
 
1023
  app.launch(server_name="0.0.0.0", server_port=7860, share=False)
1024
  except Exception as e:
1025
  logger.critical(f"No se pudo iniciar la app: {str(e)}", exc_info=True)