gnosticdev commited on
Commit
c7b9a72
·
verified ·
1 Parent(s): 40236ce

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -30
app.py CHANGED
@@ -7,37 +7,43 @@ from transformers import pipeline
7
  import requests
8
  from datetime import datetime
9
 
10
- # 1. CONFIGURACIÓN INICIAL (obtener voces sincrónicamente)
11
  VOICES = asyncio.run(edge_tts.list_voices())
12
- PEXELS_API_KEY = os.getenv("PEXELS_API_KEY") # Configura esto en Hugging Face
13
 
14
- # 2. GENERADOR DE GUIÓN CON IA
15
  def generar_guion(prompt):
16
- generator = pipeline("text-generation", model="facebook/mbart-large-50")
17
- return generator(
18
- f"Redacta un guion corto sobre '{prompt}' (4 puntos clave):",
19
- max_length=200,
20
- num_return_sequences=1
21
- )[0]['generated_text']
 
 
 
 
22
 
23
- # 3. FUNCIÓN PRINCIPAL (sincronizada para Gradio)
24
  def crear_video(prompt, script_personalizado, voz_seleccionada, musica=None):
25
  try:
26
  # A. Generar guión
27
  guion = script_personalizado if script_personalizado else generar_guion(prompt)
28
 
29
- # B. Generar voz (usando subprocess para evitar async)
30
  os.system(f'edge-tts --voice "{voz_seleccionada}" --text "{guion}" --write-media "voz.mp3"')
31
 
32
- # C. Buscar videos en Pexels
33
  headers = {"Authorization": PEXELS_API_KEY}
34
  query = prompt[:50].replace(" ", "+")
35
- videos = requests.get(
36
  f"https://api.pexels.com/videos/search?query={query}&per_page=2",
37
- headers=headers
38
- ).json().get("videos", [])
 
 
39
 
40
- # D. Procesar música
41
  audio = AudioFileClip("voz.mp3")
42
  if musica:
43
  musica_clip = AudioFileClip(musica.name)
@@ -45,7 +51,7 @@ def crear_video(prompt, script_personalizado, voz_seleccionada, musica=None):
45
  musica_clip = musica_clip.loop(duration=audio.duration)
46
  audio = CompositeAudioClip([audio, musica_clip.volumex(0.3)])
47
 
48
- # E. Crear video final
49
  clips = [VideoFileClip(v["video_files"][0]["link"]).subclip(0, 5) for v in videos[:2]]
50
  final_clip = concatenate_videoclips(clips).set_audio(audio)
51
  output_path = f"video_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
@@ -53,32 +59,34 @@ def crear_video(prompt, script_personalizado, voz_seleccionada, musica=None):
53
 
54
  return output_path
55
  except Exception as e:
56
- print(f"ERROR: {str(e)}")
57
  return None
58
 
59
- # 4. INTERFAZ GRADIO
60
- with gr.Blocks(title="Generador de Videos PRO") as app:
61
- gr.Markdown("# 🎥 GENERADOR DE VIDEOS AUTOMÁTICO")
62
 
63
  with gr.Row():
64
  with gr.Column():
65
- prompt = gr.Textbox(label="📌 Tema principal", placeholder="Ej: 'Inteligencia Artificial en 2024'")
66
- script = gr.TextArea(label="📝 Guion personalizado (opcional)", lines=5)
67
  voz = gr.Dropdown(
68
- label="🗣️ Selecciona voz",
69
  choices=[v["Name"] for v in VOICES],
70
- value="es-MX-DaliaNeural"
71
  )
72
- musica = gr.File(label="🎵 Música de fondo (opcional)", file_types=[".mp3", ".wav"])
73
- btn = gr.Button("🚀 GENERAR VIDEO", variant="primary")
74
 
75
  with gr.Column():
76
- output = gr.Video(label="🎬 VIDEO RESULTANTE", autoplay=True)
77
 
78
  btn.click(
79
  fn=crear_video,
80
  inputs=[prompt, script, voz, musica],
81
- outputs=output
 
82
  )
83
 
84
- app.launch()
 
 
7
  import requests
8
  from datetime import datetime
9
 
10
+ # 1. Configuración inicial (SIN ASYNCIO en callbacks)
11
  VOICES = asyncio.run(edge_tts.list_voices())
12
+ PEXELS_API_KEY = os.getenv("PEXELS_API_KEY")
13
 
14
+ # 2. Generador de guión (sincrónico)
15
  def generar_guion(prompt):
16
+ try:
17
+ generator = pipeline("text-generation", model="facebook/mbart-large-50")
18
+ return generator(
19
+ f"Genera un guion sobre '{prompt}' (4 puntos breves):",
20
+ max_length=200,
21
+ num_return_sequences=1
22
+ )[0]['generated_text']
23
+ except Exception as e:
24
+ print(f"Error en generación: {e}")
25
+ return prompt # Fallback al texto original
26
 
27
+ # 3. Función principal (sincrónica)
28
  def crear_video(prompt, script_personalizado, voz_seleccionada, musica=None):
29
  try:
30
  # A. Generar guión
31
  guion = script_personalizado if script_personalizado else generar_guion(prompt)
32
 
33
+ # B. Generar voz (solución sincrónica)
34
  os.system(f'edge-tts --voice "{voz_seleccionada}" --text "{guion}" --write-media "voz.mp3"')
35
 
36
+ # C. Descargar videos
37
  headers = {"Authorization": PEXELS_API_KEY}
38
  query = prompt[:50].replace(" ", "+")
39
+ response = requests.get(
40
  f"https://api.pexels.com/videos/search?query={query}&per_page=2",
41
+ headers=headers,
42
+ timeout=10
43
+ )
44
+ videos = response.json().get("videos", [])
45
 
46
+ # D. Procesar audio
47
  audio = AudioFileClip("voz.mp3")
48
  if musica:
49
  musica_clip = AudioFileClip(musica.name)
 
51
  musica_clip = musica_clip.loop(duration=audio.duration)
52
  audio = CompositeAudioClip([audio, musica_clip.volumex(0.3)])
53
 
54
+ # E. Renderizar video
55
  clips = [VideoFileClip(v["video_files"][0]["link"]).subclip(0, 5) for v in videos[:2]]
56
  final_clip = concatenate_videoclips(clips).set_audio(audio)
57
  output_path = f"video_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
 
59
 
60
  return output_path
61
  except Exception as e:
62
+ print(f"ERROR CRÍTICO: {e}")
63
  return None
64
 
65
+ # 4. Interfaz (con queue enabled=False)
66
+ with gr.Blocks(title="Generador de Videos", css="footer {visibility: hidden}") as app:
67
+ gr.Markdown("# 🎬 GENERADOR DE VIDEOS (ESTABLE)")
68
 
69
  with gr.Row():
70
  with gr.Column():
71
+ prompt = gr.Textbox(label="Tema principal", placeholder="Ej: 'Tecnología en 2025'")
72
+ script = gr.TextArea(label="Guion personalizado (opcional)", lines=5)
73
  voz = gr.Dropdown(
74
+ label="Selecciona voz",
75
  choices=[v["Name"] for v in VOICES],
76
+ value="es-ES-ElviraNeural"
77
  )
78
+ musica = gr.File(label="Música (opcional)", file_types=[".mp3"])
79
+ btn = gr.Button("Generar Video", variant="primary")
80
 
81
  with gr.Column():
82
+ output = gr.Video(label="Resultado", autoplay=True)
83
 
84
  btn.click(
85
  fn=crear_video,
86
  inputs=[prompt, script, voz, musica],
87
+ outputs=output,
88
+ api_name="generar" # Evita usar colas
89
  )
90
 
91
+ # 5. Lanzamiento (sin colas)
92
+ app.launch(enable_queue=False) # ¡Clave para evitar el error!